2011-11-09 86 views
2

我有一個表,我想隨機選擇10行。但我也需要選擇「銷售」上的任何行。我只想要只有10行,可能有2個銷售行可能有9個,我需要填充其餘的隨機行。我需要一個查詢。SQL Server選擇隨機且不是隨機的

SELECT TOP 10 BookTitle, BookAuthor, BookCategory 
FROM TheTable 
ORDER BY newid() 

SELECT TOP 10 BookTitle, BookAuthor, BookCategory 
FROM TheTable 
WHERE BookCategory LIKE 'Sale%' 

我不斷剔除,我可能是上/下想這....

感謝。

+0

如果有11個出售,該怎麼辦?那麼你需要一個隨機的10個? –

回答

4

不是很了很大的表格有效,但...

SELECT TOP 10 BookTitle, 
       BookAuthor, 
       BookCategory 
FROM TheTable 
ORDER BY CASE 
      WHEN BookCategory LIKE 'Sale%' THEN 0 
      ELSE 1 
      END, 
      newid() 

如果你的表是大你應該做2個查詢。一個獲得銷售物品,然後第二個獲得隨機非銷售物品的「充值」數量。

+0

呃......我輸入太慢了。 +1 :) –

+0

CASE是一種聰明的語言技巧,但結果很糟糕:全表掃描,構建排序表,排序,然後獲得排名前10位。對於1M行以上的每個查詢,請執行此操作。 datacenter;) –

+0

@RemusRusanu - 是的,同意它不適合大表(但是,然後再次表示樣本不適合小的表),將有助於知道涉及的行數。 –

4

在子查詢中選擇10個類別和10個隨機數。
按類別劃分優先級。

SELECT TOP 10 BookTitle, BookAuthor, BookCategory 
FROM (
    SELECT TOP 10 BookTitle, BookAuthor, BookCategory, 0 as prio 
    FROM TheTable 
    WHERE BookCategory LIKE 'Sale%') 

    UNION ALL 
    SELECT TOP 10 BookTitle, BookAuthor, BookCategory, 1 As prio 
    FROM TheTable 
    TABLESAMPLE (50 ROWS) 
    ) x 
ORDER BY prio 

我從@ Remus的答案TABLESAMPLE,因爲這顯然是與大表要快得多。爲他投票,如果這是你的主要特點。

然而,我調整它TABLESAMPLE (50 ROWS),因爲這warning in the manual的:

被返回可以顯著改變行的實際數量。如果 指定了一個小數字,例如5,則樣本中可能不會收到結果 。

我剛測試並轉載了這個。另外我還離開了TOP 10,因爲我們最終只需要最多10個。

此外,manual adds a disclamer的「隨意性」:

如果你真的要各行的隨機抽樣,修改 查詢隨機篩選出的行,而不是使用TABLESAMPLE。

所以,如果真正的隨機選擇是一項要求,您的原始newid()是正確的方法。

0

組合這兩個查詢有什麼問題嗎?

SELECT TOP 10 BookTitle, BookAuthor, BookCategory 
FROM TheTable 
ORDER BY newid() 
WHERE BookCategory LIKE 'Sale%' 
+1

是的,有一些錯誤:如果只有5件商品在'銷售'上,那麼它不會返回10行。 –

+0

所以,如果你只有2行,你還想從這2行中隨機選擇10行?你不在乎它會被重複填充嗎? – user978122

2

使用TABLESAMPLE。使用ORDER BY NEWID()的樸素方法將導致可怕的性能,因爲必須對每個查詢對整個表進行掃描和排序,以便選擇10個隨機行。內置的TABLESAMPLE語法將使用高效的IO頁採樣來提供所需的行數,並且示例隨機性對於日常使用來說已經足夠了。有關更多詳情,請參閱Limiting Result Sets by Using TABLESAMPLE

select top(10) BookTitle, BookAuthor, BookCategory 
from (
    SELECT TOP(10) BookTitle, BookAuthor, BookCategory 
    FROM TheTable 
    WHERE BookCategory LIKE 'Sale%' 
    UNION ALL 
    SELECT BookTitle, BookAuthor, BookCategory 
    FROM TheTable TABLESAMPLE (10 ROWS)) as theUnion; 

請注意,這並不能保證任何'隨機'行不是'Sale%'行之一,實際上產生重複。如果你需要這樣的排除,這可能會更復雜,而且可能效率低下。

+0

對於TABLESAMPLE爲+1。我無恥地從你那裏複製,但以修改後的形式。你可能會感興趣。此外,您的答案未能優先處理非隨機行,因此結果不能保證是正確的。 –