[英]Select random values from each group, SQL
I have a project through which I'm creating a game powered by a database. 我有一个项目,通过它我可以创建一个由数据库驱动的游戏。
The database has data entered like this: 数据库输入的数据如下:
(ID, Name) || (身份证,姓名)|| (1, PhotoID),(1,PhotoID),(1,PhotoID),(2,PhotoID),(2,PhotoID) and so on. (1,PhotoID),(1,PhotoID),(1,PhotoID),(2,PhotoID),(2,PhotoID)等。 There are thousands of entries. 有数以千计的条目。
This is my current SQL statement: 这是我当前的SQL语句:
$sql = "SELECT TOP 8 * FROM Image WHERE Hidden = '0' ORDER BY NEWID()";
But this can also produce results with matching IDs, where I need to have each result have a unique ID (that is I need one result from each group). 但是这也可以产生具有匹配ID的结果,其中我需要使每个结果具有唯一ID(即我需要来自每个组的一个结果)。
How can I change my query to grab one result from each group? 如何更改查询以从每个组中获取一个结果?
Thanks! 谢谢!
Since ORDER BY NEWID()
will result in tablescan anyway, you might use row_number() to isolate first in group: 由于ORDER BY NEWID()
无论如何都会导致表扫描,因此您可以使用row_number()来隔离组中的第一个:
; with randomizer as (
select id,
name,
row_number() over (partition by id
order by newid()) rn
from Image
where hidden = 0
)
select top 8
id,
name
from randomizer
where rn = 1
-- Added by mellamokb's suggestion to allow groups to be randomized
order by newid()
Sql Fiddle playground thanks to mellamokb. 由于mellamokb, Sql Fiddle游乐场 。
Looks like this may work, but I can't vouch for performance: 看起来这可能有用,但我无法保证性能:
SELECT TOP 8 ID,
(select top 1 name from image i2
where i2.id = i1.id order by newid())
FROM Image i1
WHERE hidden = '0'
group by ID
ORDER BY NEWID();
Demo: http://www.sqlfiddle.com/#!3/657ad/6 演示: http ://www.sqlfiddle.com/#!3 / 657ad / 6
If you have an index on the ID
column and want to take advantage of the index and avoid a full table scan, do your randomization on the key values first: 如果您在ID
列上有索引并希望利用索引并避免全表扫描,请首先对键值进行随机化:
WITH IDs AS
(
SELECT DISTINCT ID
FROM Image
WHERE Hidden = '0'
),
SequencedIDs AS
(
SELECT ID, ROW_NUMBER() OVER (ORDER BY NEWID()) AS Seq
FROM IDs
),
ImageGroups AS
(
SELECT i.*, ROW_NUMBER() OVER (PARTITION BY i.ID ORDER BY NEWID()) Seq
FROM SequencedIDs s
INNER JOIN Image i
ON i.ID = s.ID
WHERE s.Seq < 8
AND i.Hidden = '0'
)
SELECT *
FROM ImageGroups
WHERE Seq = 1
This should drastically reduce the cost over the table scan approach, although I don't have a schema big enough that I can test with - so try running some statistics in SSMS and make sure ID
is actually indexed for this to be effective. 这应该大大降低了表扫描方法的成本,虽然我没有足够大的模式可以测试 - 所以尝试在SSMS中运行一些统计信息并确保ID
实际上被索引以使其有效。
select * from (select * from photos order by rand()) as _SUB group by _SUB.id;
select ID, Name from (select ID, Name, row_number() over
(partition by ID, Name order by ID) as ranker from Image where Hidden = 0 ) Z where ranker = 1
order by newID()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.