[英]returning different results form 3 tables when the query is written the same way
您好,我有一个表格,可以按艺术家的名字选择歌手,也可以选择歌曲,然后选择日期范围并从中获取全部统计信息,我想要实现的基本上是以下内容,
问题是我写的两个查询看起来都一样,是否有另一种更好的方法来解决这个问题?
这是数据库结构
3桌
样本变量
$artist = SIA
$song = chandelier
$start_date = 2016-09-06
$end_date = 2016-09-07
样本数据库数据
播放表
A- play_id = 12 | 日期= 2016-09-06
B- play_id = 13 | 日期= 2016-09-07
C- play_id = 14 | 日期= 2016-09-07
歌曲表
A- plid = 12 | 援助= 34
B- plid = 12 | 援助= 34
C- plid = 13 | 援助= 34
D- plid = 14 | 援助= 34
E- plid = 14 | 援助= 34
艺术家表
预期结果
A-每位艺术家的演奏次数= 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'";
让我们看第二个查询...
$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生成结果集。 但是然后,您在where子句中使用了(a.artist_name= '$artist' OR s.aid = '$song')
,这将导致左侧联接中生成的NULL被排除在结果之外。
试试上面的代替
您遇到的问题是由您的数据和查询方式引起的。 从样本数据可以清楚地看出,一个播放可以包含多首歌曲。
这意味着,当您同时从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'";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.