[英]T-SQL with random returns multiple rows where one is expected
Consider the following T-SQL code (MS SQL Server 2014) that fetches a random row from a table variable: 请考虑以下T-SQL代码(MS SQL Server 2014),该代码从表变量中获取随机行:
DECLARE @priceClasses TABLE (
RowIndex INT,
PriceClassID NVARCHAR(MAX))
;
INSERT INTO @priceClasses VALUES
(0, 'RETAIL')
,(1, 'WHOLESALE')
,(2, 'WHOLESALE2')
;
DECLARE @priceClassesCount AS INT;
SET @priceClassesCount = (SELECT COUNT(*) FROM @priceClasses);
SELECT
PriceClasses.RowIndex,
PriceClasses.PriceClassID
FROM
@priceClasses AS PriceClasses
WHERE
PriceClasses.RowIndex = ABS(CHECKSUM(NEWID())) % @priceClassesCount;
The last SELECT
statement, for some reason, sometimes returns 0 rows, sometimes 1, 2, or 3 rows. 由于某种原因,最后一个
SELECT
语句有时返回0行,有时返回1、2或3行。
It does not make sense to me. 这对我来说没有意义。 The value of the column is unique, and
ABS(CHECKSUM(NEWID())) % @priceClassesCount
cannot be multi-valued, can it? 该列的值是唯一的,并且
ABS(CHECKSUM(NEWID())) % @priceClassesCount
不能为多值,可以吗?
The issue disappears when I declare RowIndex INT NOT NULL PRIMARY KEY
instead of just RowIndex INT
. 当我宣布这个问题消失
RowIndex INT NOT NULL PRIMARY KEY
,而不是仅仅RowIndex INT
。 Any thoughts? 有什么想法吗?
The WHERE
clause is evaluated once per row. WHERE
子句每行评估一次。 That is the beauty of NEWID()
. 那就是
NEWID()
的美。 Tragic beauty for your case. 您的情况的悲剧之美。
If you are going to use this method, you might as well store the value in a variable: 如果要使用此方法,则最好将值存储在变量中:
DECLARE @priceClassesCount AS INT;
SET @priceClassesCount = (SELECT COUNT(*) FROM @priceClasses);
SET @RowIndex = 1 + (ABS(CHECKSUM(NEWID())) % @priceClassesCount)
SELECT pc.RowIndex, pc.PriceClassID
FROM @priceClasses pc
WHERE pc.RowIndex = @RowIndex;
Hopefully, RowIndex
has no gaps in it. 希望
RowIndex
没有任何空白。 That could be another reason why you are getting no rows. 这可能是您没有行的另一个原因。
To get one random row, you can do this 要获得一个随机行,您可以执行此操作
SELECT TOP 1
PriceClasses.RowIndex,
PriceClasses.PriceClassID
FROM
@priceClasses AS PriceClasses
ORDER BY
NEWID();
Although @GordonLinoff is correct, the requirement has a simpler solution 尽管@GordonLinoff是正确的,但该要求具有更简单的解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.