我有两张桌子。 歌曲表,其中包含我可以收听的所有歌曲。 存档表我把播放的歌曲放在日期和时间。
我要做的是让数据库给我一首歌:
1)不要玩(不存在于档案库中)
....如果不可能
2)出现在档案馆,但至少在24小时前播放
....如果不可能
3)这是否在档案中,但歌曲的艺术家是否已经播放至少3小时
4)最后,如果没有结果,我希望数据库从歌曲表
中返回一首随机歌曲(
SELECT song.*
FROM
song AS song
LEFT JOIN
( SELECT song_artist
FROM archive
WHERE customer_id=50
AND genre=32
AND channel=44
AND archive_date < DATE_SUB(NOW(), INTERVAL 3 HOUR)
)
AS archive_a
ON song.song_artist = archive_a.song_artist
LEFT JOIN
(SELECT song_id
FROM archive
WHERE customer_id=50
AND genre=32
AND channel=44
AND archive_date < DATE_SUB(NOW(), INTERVAL 24 HOUR)
)
AS archive_b
ON song.song_id = archive_b.song_id
LEFT JOIN
( SELECT a.song_id FROM song a
LEFT JOIN archive b
ON a.song_id = b.song_id
WHERE NOT EXISTS (
SELECT null
FROM archive c
WHERE customer_id=50
AND genre=32
AND channel=44
AND c.song_id = a.song_id
)
)
AS song_c
ON song.song_id = song_c.song_id
WHERE FIND_IN_SET('32', genre) <> 0
AND archive_a.song_artist Is Null
AND archive_b.song_id Is Null
AND song_c.song_id Is Null
GROUP BY song_artist ORDER BY RAND() LIMIT 1
)
UNION
(
SELECT song.*
FROM
song AS song
WHERE FIND_IN_SET('32', genre) <> 0
GROUP BY song_artist ORDER BY RAND() LIMIT 1
)
我曾尝试过这个世界,但没有工作
答案 0 :(得分:0)
从中删除存档条件并将其用作连接条件。
答案 1 :(得分:0)
老实说,即使您可以使用联盟将其写为单个查询,我也不会这样做。原因很简单:您想要选择符合上述任何标准的随机歌曲(唱片)。
我宁愿发出一个查询,试图获取之前从未播放的歌曲,在您的应用程序中处理结果,如果没有返回记录,则继续下一个查询。
如果你坚持在一个查询中组合4个标准,那么我会编写4个查询并将它们与union组合成一个查询。另外,我不会使用rand()的顺序,因为它不能很好地扩展。我将执行查询以确定匹配每个条件的记录的数量(计数),确定0和count-1之间的随机数,并使用limit子句来选择随机记录。如果计数返回0,则可以从联合中省略该查询。