这是一个包含大约6个联合的非常长的查询的简短片段,但它们的逻辑大致相同:
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = 'Common'
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT 2)
UNION
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = ?
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT 1) 在第二个查询中,根据PHP中计算的机会来设置稀缺性。所以我得到了一个随机数,如果它低于5,那么罕见的是"Rare“,但是如果它超过5,则罕见的是"Common”。
当它得到"Common“时,问题就出现了,有时查询会选择第一个查询中已经选择的公共查询(,我不想要重复的)。有可能解决这个问题吗?我怎样才能使它避免选择一个被UNION剥离的副本?
MySQL版本5.7.30
DB Fiddle示例:https://www.db-fiddle.com/f/7wFDnYuVPt15qPorQvemrw/4
进一步解释
我需要的是:始终使用这个UNION返回3行唯一的行。
问题:它有时会返回2行,因为第二个查询最终可能会选择第一个查询中已经选择的行。
UNION ALL将不能工作,因为它将返回重复的。
发布于 2020-05-27 09:35:13
寻找
SELECT *
FROM (
-- your query
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = 'Common'
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT 2)
UNION
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = ?
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT 3) -- LIMIT enlarged to 3
-- end of your query
) subquery
ORDER BY set_rarity != 'Common', RAND() LIMIT 3如果参数不是“公共”,那么您将从子查询中得到2行“公共”行和3行非“公共”行,排序首先将拥有“公共”行,而第3行将是随机的3行非“公共”行。
如果参数是“公共”,那么您将在子查询中得到3-5行,并从它们中随机选择3行。
小提琴 (基于OP的小提琴)-总是返回3种不同的记录(当然,如果存在于源表中)。
发布于 2020-05-27 12:04:39
我将更改查询的可变部分。现在,您的参数是set_rarity (cr.set_rarity = ?)。我会让它被固定为“稀有”,但使限制可变。
假设PHP代码中有类似的内容:
if ($randomNumber > 5) {
$rarityParam = 'Common';
} else {
$rarityParam = 'Rare';
}我会把它改为:
$commonLimitParam = 2;
$rareLimitParam = 0;
if ($randomNumber > 5) {
$commonLimitParam += 1;
} else {
$rareLimitParam += 1;
}并将上述参数绑定到以下查询:
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = 'Common'
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT ?)
UNION
(SELECT cr.id, cr.price, cd.times, cd.name, cr.set_rarity, cd.type, cd.currentPrice_tcg
FROM card_sets_rarity cr
JOIN card_database cd
ON cr.id = cd.id
WHERE cr.set_rarity = 'Rare'
AND cr.set_name = 'Dark Beginning 1'
AND cd.type = 'Spell Card'
GROUP BY cd.id ORDER BY RAND() LIMIT ?) https://stackoverflow.com/questions/62039737
复制相似问题