从列表中选择随机数

时间:2015-03-08 14:15:05

标签: sql sql-server sql-server-2008

这是我的查询。

SELECT TOP 2 NUM 
FROM QT_PIVOT
WHERE NUM BETWEEN 1 AND 45 
ORDER BY NEWID()

我从列表中选择了2个随机数,但我不希望这些数字是连续的

有时结果是

NUM
----
2
3

我不想要这个

谢谢,对不起我的英文u.u

2 个答案:

答案 0 :(得分:0)

一种方法是选择第一个数字,然后选择合适的第二个数字:

WITH r AS (
      SELECT TOP 1 num
      FROM QT_PIVOT
      WHERE NUM BETWEEN 1 AND 45
      ORDER BY NEWId()
     )
select num
from r
union all
select top 1 q.num
from qt_pivot q join
     r
     on q.num not in (r.num, r.num - 1, r.num + 1)
where q.num between 1 and 45 
order by newid();

另一种方法(如果你有SQL Server 2012+)将使用lag()删除任何不符合条件的可能性:

WITH r AS (
      SELECT num, row_number() over (order by newid()) as seqnum
      FROM QT_PIVOT
      WHERE NUM BETWEEN 1 AND 45
     )
SELECT r.num
FROM (SELECT r.*, LAG(num) OVER (ORDER BY seqnum) as prevnum
      FROM r
     ) r
WHERE prevnum is null or
      prevnum not in (num - 1, num + 1);

编辑:

第一种方法不起作用,因为SQL Server 总是重新评估CTE,甚至没有提示来解决这个问题。这是一种替代方法,可确保值不连续:

WITH r as (
      SELECT (1 + checksum(newid()) * 45) as r1,
             (2 + checksum(newid()) * 43) as r2
     )
SELECT q.num
FROM QT_PIVOT q
WHERE q.num = r.r1 or
      q.num = 1 + (r.r1 + r.r2) % 45;

这计算两个随机数。第一个是随机位置。第二个是允许的偏移(因此“2”和“43”),以保证数字不相邻。

答案 1 :(得分:0)

基本上与Gordon使用的第二种方法相同,只是它没有使用滞后函数,因此它将适用于SQL-2008。

WITH Data AS(
    SELECT *, RowNum = ROW_NUMBER() OVER (ORDER BY NEWID())
    FROM sys.objects AS O
),
r AS(
    SELECT TOP 1 *, SkipRow = 0
    FROM Data
    WHERE Data.RowNum = 1
    UNION ALL
    SELECT d.*, SkipRow = CASE WHEN d.object_id BETWEEN r.object_id -2 AND r.object_id + 2 THEN 1 ELSE 0 END 
    FROM r
        JOIN Data AS D
            ON r.RowNum + 1 = D.RowNum
)
SELECT TOP 2 * FROM R
WHERE R.SkipRow = 0
相关问题