2015-05-21 59 views
4

是否可以基於密鑰隨機化SELECT?基於密鑰的隨機SELECT查詢

我用這個查詢隨機我的查詢:

SELECT * FROM tbl_news ORDER BY NEWID(); 

是否有一個函數或基於這樣像這樣隨意查詢關鍵

SELECT * FROM tbl_news ORDER BY NEWID(15); 

5,1,3,2,4 

隨着相同關鍵字:

SELECT * FROM tbl_news ORDER BY NEWID(15); 

5,1,3,2,4 

隨着另一鍵:

SELECT * FROM tbl_news ORDER BY NEWID(36); 

2,5,1,3,4 
+0

@DmitryBychenko:那這麼想的工作,因爲蘭特將返回相同的行 – Arion

+0

@DmitryBychenko不,一鍵(例如15)定義了隨機的圖案。 – Mike

+0

只是NEWID(),沒有任何種子? – jarlh

回答

2

你可以使用HASHBYTES,雖然它可能不是一個大數目的行出色表演(雖然同樣沒有NEWID()),例如

-- CREATE SAMPLE DATA 
IF OBJECT_ID(N'tempdb..#tbl_news', 'U') IS NOT NULL DROP TABLE #tbl_news; 
CREATE TABLE #tbl_news (NewsID INT IDENTITY); 
INSERT #tbl_news DEFAULT VALUES; 
INSERT #tbl_news DEFAULT VALUES; 
INSERT #tbl_news DEFAULT VALUES; 
INSERT #tbl_news DEFAULT VALUES; 
INSERT #tbl_news DEFAULT VALUES; 

-- DEFINE YOUR SORT KEY 
DECLARE @Key INT = 15; 

SELECT * 
FROM #tbl_news 
ORDER BY HASHBYTES('MD5', CONVERT(VARCHAR(10), NewsID + @Key)); 

-- SAME ORDER AS FIRST SELECT TO SHOW SORT IS REPEATABLE 
SELECT * 
FROM #tbl_news 
ORDER BY HASHBYTES('MD5', CONVERT(VARCHAR(10), NewsID + @Key)); 


SET @Key = 36; 

-- WITH A NEW KEY SHOW DIFFERENT ORDER 
SELECT * 
FROM #tbl_news 
ORDER BY HASHBYTES('MD5', CONVERT(VARCHAR(10), NewsID + @Key)); 

-- BUT NEW ORDER IS STILL REPEATABLE 
SELECT * 
FROM #tbl_news 
ORDER BY HASHBYTES('MD5', CONVERT(VARCHAR(10), NewsID + @Key)); 
+0

你的代碼對我來說工作正常,但是對於大量的行有沒有辦法? – Mike

+1

我可能實際上已經說過了,性能並沒有比'NEWID()更糟糕,我剛剛在超過750k行的表上運行比較,並且使用哈希字節進行排序需要15s才能完成,並且使用'NEWID()'的排序需要14s(平均每個5次) – GarethD

0

你想要什麼叫隨機種子。請參閱here。種子使隨機數可重複。我認爲解決方案是使用種子並將它們放入表中,然後將此表與表聯接起來以找到您想要的列表。看下面的例子。

DECLARE @SEED INT = 100; 
DECLARE @SIZE INT = 5; 
-- url http://www.codeproject.com/Tips/811913/Generating-a-set-of-random-numbers-in-SQL-Server 
WITH RandomNumbers (RowNumber, RandomNumber) AS (
    -- Anchor member definition 
    SELECT 1       AS RowNumber, 
      RAND(@SEED) AS RandomNumber 
    UNION ALL 
    -- Recursive member definition 
    SELECT rn.RowNumber + 1   AS RowNumber, 
      RAND(1000000000* RAND(@SEED + rn.RowNumber)) AS RandomNumber 
    FROM RandomNumbers rn 
    WHERE rn.RowNumber < @SIZE 
) 
-- Statement that executes the CTE 
SELECT rn.RowNumber, rn.RandomNumber 
FROM RandomNumbers rn 
INNER JOIN tbl_news n 
ON rn.RowNumber = n.ID 
ORDER BY rn.RandomNumber