SQL-即使存在少于X条记录,也可以检索顶部(X)条记录
在我的应用程序中,有几个地方向用户显示一组随机的X项。用户界面要求显示X个项目。但是,不能保证表中有X项。因此,如果没有X项,我需要用随机重复项填充结果 我需要编写一个基本上是:SQL-即使存在少于X条记录,也可以检索顶部(X)条记录,sql,random,Sql,Random,在我的应用程序中,有几个地方向用户显示一组随机的X项。用户界面要求显示X个项目。但是,不能保证表中有X项。因此,如果没有X项,我需要用随机重复项填充结果 我需要编写一个基本上是: SELECT TOP(@count) * FROM Things ORDER BY NEWID() 我希望能够向SQL请求X条记录,并且每次都能准确地返回X条记录。有没有一种简单的方法可以在SQL中实现这一点 谢谢。可以在T-SQL中完成: SELECT * FROM ( SELECT TOP(@count) *
SELECT TOP(@count) *
FROM Things
ORDER BY NEWID()
我希望能够向SQL请求X条记录,并且每次都能准确地返回X条记录。有没有一种简单的方法可以在SQL中实现这一点
谢谢。可以在T-SQL中完成:
SELECT *
FROM (
SELECT TOP(@count) *
FROM Things
ORDER BY NEWID()
) x
UNION ALL
SELECT DummyValuesHere
FROM Numbers
WHERE Numbers.ID <= (@count - (SELECT COUNT(*) FROM Things))
你需要一个数字表。我们只是将所有正确数量的伪行追加到UNION中
现在你知道查询是多么可怕了,考虑一下在应用程序中做这项工作吧。SQL不是用于此类查询的好工具。好吧,我有一个解决方案,但我仍然认为要求很荒谬。这假设在我的例子中,源表@t至少有一行。如果你有零行,你到底在演示什么
DECLARE @count INT = 17; -- here is whatever your 'X' is; pick any value
DECLARE @t TABLE(i INT);
-- just insert 10 arbitrary values; test with @count = 5, @count = 247, etc.
INSERT @t VALUES(150),(170),(50),(100),(200),(230),(20),(800),(180),(632);
DECLARE @x INT; SELECT @x = COUNT(*) FROM @t;
SELECT TOP (@count) x.* FROM
(
-- limit this set to @count:
SELECT TOP (@count) * FROM @t ORDER BY NEWID()
) AS x
OUTER APPLY
(
-- limit this set the ratio of @count to rows in @t
-- add one to round up for integer division:
SELECT TOP (@count/@x+1) * FROM sys.all_objects
WHERE @count > @x -- only evaluate this subquery if we don't have enough rows
) AS y
ORDER BY NEWID(); -- need a 2nd ORDER BY in my tests to avoid pockets of same values
帽子提示。我最终创建了自己的解决方案
DECLARE @count INT = 10;
DECLARE @ids TABLE(id INT);
WHILE ((SELECT COUNT(*) FROM @ids) < @count)
BEGIN
INSERT INTO @ids
SELECT TOP(@count) ID
FROM Things
ORDER BY NEWID()
END
SELECT TOP(@count) t.*
FROM Things t
JOIN @ids ON t.ID = [@ids].id
快速浏览表数据有助于解决查询性能问题, 它可以帮助识别重复出现的值、空值和理解数据 我认为Aaron有最好的答案,不过我要说的是,答案是使用TOP。。。NEWID的订单对于大型表有很大的性能问题, 它们至少会导致一次完整的索引聚集扫描或不扫描, 因为顶部是在排序之后完成的,而排序是在 所有记录的新ID 讨论了另一种解决办法 使用二进制校验和,但根据评论似乎有缺陷 另一个简单的解决方案是使用添加到Sql2005中的TABLESAMPLE选项
SELECT * FROM Sales.SalesOrderDetail TABLESAMPLE (1000 ROWS)
看
然而,它们是其使用的条件
.. 样本不必是单个行级别的真正随机样本。
表的各个页面上的行与同一页面上的其他行不相关。
根据描述和注释,输出似乎不是完全随机的。
而且,输出并不总是具有所需的行数,您希望SQL做什么?创建新数据?我认为这是一个需要解决的有趣问题。如果我愿意的话,我可以很容易地用C语言完成这项工作。我觉得如果有一种简单的方法可以在sql中实现,并且我只能对DB进行一次调用,那么它将是干净高效的。讽刺是不受欢迎的TOP@countT.*根据T CROSS APPLY sys.allcolumns SAC ORDER BY newid这个应用程序在视图中有几个地方显示了一组随机的X项,它需要的正好是X项。为什么要求DB提供一组随机的X项并期望结果中有X项是如此愚蠢?@Seattleonard其核心问题是有效的,但它没有明确说明填充行应该包含什么?。因此,很容易赢得仇恨,因为确实存在许多可怕的问题。对于我们这些回答很多的人来说,这是令人沮丧的。在这个问题上的仇恨是错误的。很抱歉。试着以一种明确的方式再次询问这个问题。除了我不想要伪值。向用户展示一堆糟糕的数据是愚蠢的。@Seattleonard好吧,你没有说你想展示什么:只要在联盟的第二部分插入你想要的任何东西就行了。你甚至可以从事物中提取回填行。@Seattleonard有人可能会说,再显示第1行、第1行、第2行、第2行、第2行同样愚蠢。在@count=5的情况下,表中只有2行。有人可能会说,但也有人可能会说,距离我很远的人编写的应用程序的要求也很愚蠢@西雅图:你能详细说明他们在始终精确显示n行时看到了什么价值,即使其中包含冗余的重复项?这真的是为了避免将任何逻辑编码到应用程序中,以便它了解实际存在的行数吗?谢谢您给出了问题的实际答案。在我的例子中,我们可以假设至少有一行。为什么要使用WHILE循环呢?你检查过性能了吗?@AaronBertrand谁需要设置逻辑?!?!不要再吝啬了。99.9999%的时候,while循环本质上只是一个运行两次的if语句。一次启动循环,一次退出循环。如果sql有do/while,它将只检查一次。考虑到我愚蠢的要求,我认为这是一个合理的妥协。@Seattleonard重点不是你选择循环结构,而是你选择了循环结构而不是基于集合的解决方案。关系模型是基于集合的,因此使用Aaron提供的基于集合的解决方案将获得最佳性能。此外,给试图帮助你的人打电话不是继续获得帮助的好方法。落选票将会到来
因为在面对其他答案时,您给出了一个不太好的答案。与仅检索10条记录相比,数千条记录的外部应用不会对性能产生影响吗?