我有以下destination
,image
和destination_image
表:
(MYSQL):
我需要为每个目的地选择给定大小的随机 N个图像;其中N在运行时定义,目的地从id_destination
范围内选择。
我不需要top
N张图片,只需随机 N张图片。
有人能指出我正确的SQL查询方向吗?
答案 0 :(得分:1)
尝试类似ORDER BY RAND() LIMIT N
的内容,其中N
是应返回的结果数。例如:
SELECT i.id_image FROM image i
JOIN destination_image di ON i.id_image = di.id_image
WHERE di.id_destination > N AND di.id_destination < M
AND i.size = X
ORDER BY RAND() LIMIT Y
将N
,M
,X
和Y
替换为您的值。
答案 1 :(得分:1)
如果你想要每个目的地的“x”条目,你可以根据MySQL变量做...类似
select
di.id_destination,
di.id_image,
i.filepath,
i.size,
@RandSeq := if( @lastDestination = di.id_destination, @RandSeq +1, 1 ) as FinalSeq,
@lastDestination := di.id_destination as carryForward
from
destination_image di
join image i
on di.id_image = i.id_image,
( select @lastDestination := 0,
@RandSeq := 0 ) SQLVars
where
di.id_destination between rangeStart and rangeEnd (or similar criteria for your "range" )
having
FinalSeq = 4 ( just a sample, but your "N" entries per destination desired)
order by
id_destination,
rand()
这将获得4个(或您的情况下为“N”)条目PER Destination。关键是订单。 order by将以FIRST的顺序返回记录,然后应用@sql变量。因此,在每个目标上,行将首先被省略RAND(),但是在单个目标中随机出现...并且在下一个目标上相同,然后是下一个...然后@vars生成1,2,3等等“FinalSeq”列。 “HAVING”子句限制哪些行允许在最后一行中返回具有该条件的条目,因此每个示例只有4行。
SQL的澄清。
@variables几乎就像在SQL语句中使用的内联变量...通过执行(选择@someVar:= someValue,@ anotherVar:='',@ someDateVar:= getdate())作为SQLVars ...基本上只需创建和初始化可以根据查询要处理的每一行设置,更改和更新的变量...在SQL语句结束时,然后释放变量。有些人将它们预先声明为单独的SET命令,然后运行SQL-Select ..我更喜欢在线执行它们。
现在,如何使用它们......它们可用于跟踪SQL-select语句返回的任何行的几乎任何内容,但是如果您需要按特定顺序排序,则首先处理order子句,然后传递记录以使用@vars处理......所以,想想在程序中设置的@vars。它们按照SQL命令处理顺序设置为1,无论最终结果如何,都会像任何其他类似的函数调用一样存储到最终列名中,例如填充,修剪,上部,合并等。
现在,发生了什么......让我们来看看这些步骤......假设为了理解,我们有一个表,10行对应1 = A,2 = B,3 = C - - 10 = J.这些是记录的自然顺序,例如自动增量。现在,如果你要通过rand()运行查询select * from table order,你可能得到3-C,9-I,2 = B,7 = G等...这只有LIMIT 4,只会返回前4,你就完成了。
现在,分别采用相同的记录1-10 = A-J。现在,让我们展开以允许您拥有多个目的地和大小的“组”,例如......
ID Ltr Dest Size
1 A X a
2 B Y a
3 C X a
4 D X a
5 E Y b
6 F X c
7 G Y b
8 H X a
9 I Y a
10 J X b
11 K X a
12 L Y a
13 M X a
14 N Y a
现在,你想要所有目的地的东西,但是单个尺寸“a”例如...我添加了一些额外的东西。
select * from SampleTable where Size="a" order by rand()
您可以获得所有“X”目的地,或“Y(a)”记录和“X(a)”记录,或其他类似的可用余额。但是,不保证您获得大小为“a”的3“X”和3“Y”记录。如果你将ORDER改为ORDER BY Dest,rand(),这将把所有“X”条目放在第一位,那么“Y”是一个限制不起作用......所以,应用我选择的原则,你按目的地和随机排序,并应用一个大小=“a”的where子句,你可能得到......(首先按目的地,然后随机...
13 M X a
3 C X a
8 H X a
1 A X a
11 K X a
4 D X a
9 I Y a
14 N Y a
2 B Y a
12 L Y a
现在,将@variables应用于混合......只需应用@RandSeq和@lastDestination
@RandSeq:= if(@lastDestination = di.id_destination,@ RandSeq +1,1)作为FinalSeq,@ popDestination:= di.id_destination作为carryForward
Start Value of
ID Ltr Dest Size @RandSeq @lastDestination FinalSeq carryForward
13 M X a 0 '' 1 X (current record value of dest)
3 C X a 1 X 2 X
8 H X a 2 X 3 X
1 A X a 3 X 4 X
11 K X a 4 X 5 X
4 D X a 5 X 6 X
9 I Y a 6 X 1 Y (change to Y resets counter to 1)
14 N Y a 1 Y 2 Y
2 B Y a 2 Y 3 Y
12 L Y a 3 Y 4 Y
现在,如果您应用“HAVING”子句FinalSeq&lt; = 3,您将获得上面列出的所有行,其中FinalSeq&lt; = 3,并且将忽略目标“X”的剩余4,5,6 ,“Y”中的4个将被忽略...从而从给定大小的每个目的地留下3个。
希望这可以澄清查询的内容。