首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

為何 ORDER BY 不能直接用在 UNION 子句中?解決方案

     編輯:關於SqlServer

需求:從表隨機抽取 5 筆 type=1 與 5 筆 type=0,合併輸出。直覺寫法:

SELECT TOP 5 * FROM xxx WHERE type=1 ORDER BY NEWID()
UNION
SELECT TOP 5 * FROM xxx WHERE type=0 ORDER BY NEWID();
-- Msg 156: Incorrect syntax near the keyword 'ORDER'.

原因

UNION 作業會合併結果集並排序去重,ORDER BY 只能放在最外層 (最終結果),不能放在各子查詢內 (除非搭配 TOP 或 FOR XML)。

正確寫法

  1. 使用子查詢 + TOP (SQL Server 允許 TOP ... ORDER BY 在子查詢):
SELECT * FROM (
  SELECT TOP 5 * FROM xxx WHERE type=1 ORDER BY NEWID()
) t1
UNION
SELECT * FROM (
  SELECT TOP 5 * FROM xxx WHERE type=0 ORDER BY NEWID()
) t2;
  1. 使用 UNION ALL + 外層排序 (不去重、效能較好):
SELECT * FROM (
  SELECT TOP 5 * FROM xxx WHERE type=1 ORDER BY NEWID()
) t1
UNION ALL
SELECT * FROM (
  SELECT TOP 5 * FROM xxx WHERE type=0 ORDER BY NEWID()
) t2;
-- 若需最終隨機順序,再包一層 ORDER BY NEWID()
  1. 使用 ROW_NUMBER() 分區排序 (單查詢):
WITH Ranked AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY type ORDER BY NEWID()) AS rn
  FROM xxx
  WHERE type IN (0,1)
)
SELECT * FROM Ranked WHERE rn <= 5;

總結

  • ORDER BY 僅允許在 TOP/OFFSET-FETCH 子查詢或最外層。
  • UNION ALL 優於 UNION (除非需去重)。
  • 窗口函數 ROW_NUMBER() 為現代標準寫法,單掃描、可讀性佳。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved