简体   繁体   English

带有随机的T-SQL返回多行,期望其中的一行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM