2015-05-21 60 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