你好,我有一个表格,我可以通过他的名字选择艺术家或选择一首歌并选择一个日期范围并从中获取统计数据,我想要实现的基本上是以下,
问题是我写的两个查询看起来都一样,是否有另一种方法可以更好地解决这个问题?
这是数据库结构
3桌
示例变量
$artist = SIA
$song = chandelier
$start_date = 2016-09-06
$end_date = 2016-09-07
示例数据库
播放表格
A- play_id = 12 | date = 2016-09-06
B- play_id = 13 | date = 2016-09-07
C- play_id = 14 | date = 2016-09-07
歌曲表
A- plid = 12 |援助= 34
B-plid = 12 |援助= 34
C-plid = 13 |援助= 34
D-plid = 14 |援助= 34
E-plid = 14 |援助= 34
艺术家表
预期结果
每位艺术家的数量= 3
B-每位艺术家的歌曲数量= 5
查询歌曲(这是正常工作并计算歌曲的相关性)
$q2 = "
SELECT *
FROM songs s
LEFT
JOIN plays p
ON p.play_id = s.plid
LEFT
JOIN artist a
ON a.aid = s.aid
WHERE (a.artist_name = '$artist' OR s.aid = '$song')
AND date BETWEEN '$start_date' AND '$end_date'";
查询播放(此播放返回与查询相同的结果,歌曲应返回此艺术家的播放次数)
$q1 = "
SELECT *
FROM plays p
LEFT
JOIN songs s
ON s.plid = p.play_id
LEFT
JOIN artist a
ON a.aid = s.aid
WHERE (a.artist_name= '$artist' OR s.aid = '$song')
AND date BETWEEN '$start_date' AND '$end_date'";
答案 0 :(得分:1)
让我们看看第二个问题......
$q1 = "
SELECT *
FROM plays p
LEFT
JOIN songs s
ON s.plid = p.play_id
LEFT
JOIN artist a
ON a.aid = s.aid
WHERE (a.artist_name= '$artist' OR s.aid = '$song')
AND date BETWEEN '$start_date' AND '$end_date'";
可能需要成为......
$q1 = "
SELECT *
FROM plays p
LEFT JOIN songs s
ON s.plid = p.play_id
LEFT JOIN artist a
ON a.aid = s.aid
and (a.artist_name= '$artist' OR s.aid = '$song')
WHERE date BETWEEN '$start_date' AND '$end_date'";
正在发生的事情是LEFT连接根据需要生成带有NULL的结果集。但是你有(a.artist_name= '$artist' OR s.aid = '$song')
在where子句中,会导致在左连接中生成的NULLS从结果中排除。
尝试以上代替
答案 1 :(得分:0)
您遇到的问题是由您的数据和查询方式引起的。从样本数据中可以清楚地看出,单个播放可以有多首歌曲。
这意味着,当您列出来自plays
和songs
表格的匹配记录时,记录的数量将会返回由songs
表确定,因为它有重复的数据。
要获取播放次数,您需要计算查询返回的不同 play ids
的数量。由于song
表中的重复,简单计数将返回5。另外,你不需要@xQbert所解释的左连接,所以我只使用内连接,因为你只想要匹配的连接。我还删除了对歌曲的过滤,因为你坚持第二个查询应该返回给定艺术家的播放次数。您可以自由添加该条件。
$q1 = "
SELECT count(distinct p.play_id) as count_of_plays
FROM plays p
INNER
JOIN songs s
ON s.plid = p.play_id
INNER
JOIN artist a
ON a.aid = s.aid
WHERE a.artist_name= '$artist'
AND date BETWEEN '$start_date' AND '$end_date'";