繁体   English   中英

以相同方式编写查询时,从3个表返回不同的结果

[英]returning different results form 3 tables when the query is written the same way

您好,我有一个表格,可以按艺术家的名字选择歌手,也可以选择歌曲,然后选择日期范围并从中获取全部统计信息,我想要实现的基本上是以下内容,

  • 获得打数
  • 获取歌曲数

问题是我写的两个查询看起来都一样,是否有另一种更好的方法来解决这个问题?

这是数据库结构

3桌

  • 播放 :play_id | 日期
  • 歌曲 :plid | 援助
  • 艺术家 :援助| artist_name

样本变量

$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

艺术家表

  • 急救= 34 | artist_name = SIA

预期结果

  • 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被排除在结果之外。

试试上面的代替

您遇到的问题是由您的数据和查询方式引起的。 从样本数据可以清楚地看出,一个播放可以包含多首歌曲。

这意味着,当您同时从playssongs表中列出匹配的记录时,返回的记录数将由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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM