[TSQL]在SELECT DISTINCT 狀況下使用 Order BY Newid() 亂數選出

在日常作業中,有時候可能是一些活動要抽出得獎人或選出抽查的一些名單,
就常常會使用到 Order BY Newid() 的方式來做亂數選出,
但有可能的狀況需是要搭配到 DISTINCT 來選出,這時候如 DISTINCT 與 Order By Newid()
同時使用就會遇到錯誤訊息「如果已指定 SELECT DISTINCT,則 ORDER BY 項目必須顯示於選取清單中」。

在日常作業中,有時候可能是一些活動要抽出得獎人或選出抽查的一些名單,
就常常會使用到 Order BY Newid() 的方式來做亂數選出,
但有可能的狀況需是要搭配到 DISTINCT 來選出,這時候如 DISTINCT 與 Order By Newid()
同時使用就會遇到錯誤訊息「如果已指定 SELECT DISTINCT,則 ORDER BY 項目必須顯示於選取清單中」。
以下這個範例,就分享一個最簡單的處理辦法。
這邊範例的資料庫是使用 章立民 老師書中的範例中文北風資料庫,
透過用中文的範例資料庫,讓大家可以比較親近一些,來瞭解這個範例的效果。
image 
如果想在這群 DISTINCT 資料中亂數選初10筆,
則你有可能會直接聯想到使用
SELECT DISTINCT 員工編號,送貨城市
FROM dbo.訂貨主檔
Order by newid()
當然因為 DISTINCT 內在最篩選資料時,沒有 newid() 則一定會發生
如果已指定 SELECT DISTINCT,則 ORDER BY 項目必須顯示於選取清單中」。
image
那有可能就會想說,把 newid() 加進去SELECT 裡面,這樣Order BY 就沒問題了,
這樣使用的話,效果可能你會發現是跟全部SELECT一樣的效果。

所以說的那麼多,解決的方法是什麼呢?
就是把 DISTINCT(篩選) 與 Order By Newid() 亂數排序分成兩個查詢,在組合在一起,

SELECT TOP 10  *
FROM -- 模擬一個資料表
(
SELECT DISTINCT 員工編號,送貨城市
FROM dbo.訂貨主檔
) AS 虛構出來的資料表
Order by newid()

image

就透過先篩選的子查詢,在使用 newid() 就能過將這樣的功能輕鬆的做出來。