这是我的查询。
SELECT TOP 2 NUM
FROM QT_PIVOT
WHERE NUM BETWEEN 1 AND 45
ORDER BY NEWID()
我从列表中选择了2个随机数,但我不希望这些数字是连续的
有时结果是
NUM
----
2
3
我不想要这个
谢谢,对不起我的英文u.u
答案 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