TSQL-ORDER BY clause in a CTE expression?

Viewed 17230

Can we use ORDER BY clause in a CTE expression?

;with y as
(
     select 
         txn_Date_Time, txn_time, card_No, batch_No, terminal_ID
     from 
         C1_Transaction_Information
     where 
         txn_Date_Time = '2017-10-31'
     order by 
         card_No
)
select * from y;

Error message:

Msg 1033, Level 15, State 1, Line 14
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.

Msg 102, Level 15, State 1, Line 25
Incorrect syntax near ','.

4 Answers

A good alternative is to use ROW_NUMBER inside the CTE:

;with y as
(
     select  
         rn = ROW_NUMBER() OVER (ORDER BY card_No),
         txn_Date_Time, 
         txn_time, 
         card_No, 
         batch_No, 
         terminal_ID
     from 
         C1_Transaction_Information
     where 
         txn_Date_Time = '2017-10-31'
)
select txn_Date_Time, 
         txn_time, 
         card_No, 
         batch_No, 
         terminal_ID
from y 
order by rn;

This gives you the option to then select TOP 10 as TOP ...ORDER BY is not allowed within a CTE:

;with y as
(
     select  
         rn = ROW_NUMBER() OVER (ORDER BY card_No),
         txn_Date_Time, 
         txn_time, 
         card_No, 
         batch_No, 
         terminal_ID
     from 
         C1_Transaction_Information
     where 
         txn_Date_Time = '2017-10-31'
)
select txn_Date_Time, 
         txn_time, 
         card_No, 
         batch_No, 
         terminal_ID
from y 
where rn <= 10;

You can't use "Order By" in a CTE but you can move the order by to the select statement calling the CTE and have the affect I believe you are looking for

;with y as(
select txn_Date_Time,txn_time,card_No,batch_No,terminal_ID
from C1_Transaction_Information
where txn_Date_Time='2017-10-31'

)

select * from y order by card_No;

You can use ORDER BY in a cte if the cte delivers JSON

WITH cte(n) AS (
    SELECT 1
    UNION ALL
    SELECT 2
), cte2(j) AS (
    SELECT n 
    FROM cte
    ORDER BY n
    FOR JSON PATH
)
SELECT * FROM cte2;

enter image description here

The rationale is you can use ORDER BY in final output. Before final output, you can keep the columns necessary for the ordering to be called later.

Related