Can I depend on order of output when using row_number()

后端 未结 4 1176
孤独总比滥情好
孤独总比滥情好 2021-01-21 09:09

I believe the answer is no. And am looking for a counter example to show that order of output is not guaranteed, absent an order by clause.

相关标签:
4条回答
  • 2021-01-21 09:13

    As mentioned, you can't rely on row order without an ORDER BY.

    However, you can rely on the ROW_NUMBER() function value.

    SELECT
        principal_id, name, 
        ROW_NUMBER() OVER (ORDER BY principal_id DESC) AS DemoRank
    FROM
        msdb.sys.database_principals
    ORDER BY
        name
    

    If you consume the data in your client by DemoRank, then you would be OK, even without the ORDER BY clause

    If you rely on recordset ordering (ordinal index), then no.

    The example above gives first row (index = 0) as '##MS_PolicyEventProcessingLogin##', but using DemoRank value gives "db_denydatawriter"

    Basically, use ORDER BY.

    0 讨论(0)
  • 2021-01-21 09:22

    If you want it ordered, you must use ORDER BY.

    just look at the execution plan with

    SET SHOWPLAN_ALL ON
    

    if there is no "order by" in the StmtText column, you just get things however they are sorted after all the work is done. Sometimes you get lucky, sometime not, with how the data is stored/loaded/filtered/joined, etc. and how it is returned.

    0 讨论(0)
  • 2021-01-21 09:34

    If you want an ordered result set, add an ORDER BY clause to your SELECT. Period. Anything else is circumstantial and may or may not work depending on the current SQL build you're testing, the day's mood of the optimizer and the phase of Mars transit in Pisces.

    A trivial example that contradicts your assumption:

    select orderId, CustomerId, orderDateTime
        , row_number() over (partition by customerId order by orderDateTime) RN
        , row_number() over (partition by orderDateTime order by customerId) AntiRN
    from #order
    
    0 讨论(0)
  • 2021-01-21 09:36

    Im struggling to find the relevance here; if you want explicit ordering the recommended way would be to use an ORDER BY clause in the query.

    I would never rely on the default ordering of a table when producing a query that I relied on the order of the results. Any modern RDBMS is going to be able to optimize an order by based on indexes and the like, so it's not something that has to be worried about.

    In regards to row_number, while it is a side effect that if no ORDER BY clause exists, the output is ordered by the ROW_NUMBER value, you cannot depend on this behavior, as it is not guaranteed.

    Again, the only way to guarantee order of the output is with an ORDER BY clause.

    0 讨论(0)
提交回复
热议问题