我有以下查询:
SELECT
u.username as username,
s.campaignno as campaign,
if(f.hometeamscore>f.awayteamscore,1,0) as Win,
if(f.hometeamscore=f.awayteamscore,1,0) as Draw,
if(f.hometeamscore<f.awayteamscore,1,0) as Loss,
f.hometeamscore as Goals,
ss.seasonid as Season,
av.avatar as Avatar
FROM
avatar_avatar av,
straightred_fixture f,
straightred_userselection s,
auth_user u,
straightred_season ss
WHERE
av.user_id = u.id
AND ss.seasonid = 1025
AND f.soccerseasonid = ss.seasonid
AND s.fixtureid = f.fixtureid
AND s.teamselectionid = f.hometeamid
AND s.user_id = u.id;
此查询按预期工作,但我现在已经意识到用户可能没有上传个人资料图片。因此,以下部分av.user_id = u.id
排除了未上传个人资料照片的任何人。在阅读以下https://www.w3schools.com/sql/sql_join.asp
之后,我觉得我需要使用左连接,但我只是继续绕圈而无处可去。
非常感谢任何对此的指导,非常感谢,Alan。
答案 0 :(得分:1)
我喜欢使用JOIN,所以我重写了这样的查询。
请注意,我使用SQL SERVER / ORACLE而不是MYSQL,因此不确定我的语义是否正确。我使用 IFNULL 函数,因为至少在我的世界中,使用行不可用的列可能导致整个结果被过滤掉。
此外,将 ss.seasonid = 1025 移入联接,而不是将其留在 中,无论是否存在 ss,都应该获得结果记录。
尽管如此,这应该可以解决您的问题:
编辑 - 用IFNULL取代ISNULL
select
u.username as username
,s.campaignno as campaign
,if(ifnull(f.hometeamscore,0)>ifnull(f.awayteamscore,0),1,0) as Win
,if(ifnull(f.hometeamscore,0)=ifnull(f.awayteamscore,-1),1,0) as Draw
,if(ifnull(f.hometeamscore,0)<ifnull(f.awayteamscore,0),1,0) as Loss
,f.hometeamscore as Goals
,ss.seasonid as Season
,av.avatar as Avatar
from
auth_user u
Left Join
avatar_avatar av on u.id = av.user_id
Left Join
straightred_userselection s on u.id = s.user_id
Left Join
straightred_fixture f on f.hometeamid = s.teamselectionid
and f.fixtureid = s.fixtureid
Left Join
straightred_season ss on f.soccerseasonid = ss.seasonid
and ss.seasonid = 1025
答案 1 :(得分:1)
首先:避免隐式JOIN
。明确JOIN
,您将更清楚哪个实体与哪个实体相关,您永远不会忘记在AND
中添加WHERE
个条件之一并获得笛卡尔产品
第二:尝试使用遵循某个逻辑的顺序将表放在FROM
中。在你的情况下,你似乎开始寻找ss.seasonid = 1025
...(这是WHERE
有一个常数的唯一条件)。然后,您的条件列表会产生一定的逻辑顺序...... FROM
中的每个表都与前一个表有关系......
那就是说,我认为你需要这个查询:
SELECT
u.username as username,
s.campaignno as campaign,
if(f.hometeamscore>f.awayteamscore,1,0) as Win,
if(f.hometeamscore=f.awayteamscore,1,0) as Draw,
if(f.hometeamscore<f.awayteamscore,1,0) as Loss,
f.hometeamscore as Goals,
ss.seasonid as Season,
av.avatar as Avatar
FROM
straightred_season ss
JOIN straightred_fixture f
ON f.soccerseasonid = ss.seasonid
JOIN straightred_userselection s
ON s.fixtureid = f.fixtureid AND s.teamselectionid = f.hometeamid
JOIN auth_user u
ON u.id = s.user_id
-- This last table is the one that needs to be LEFT-joined
-- if the avatar is *optional*. If it isn't there, av.avatar will just
-- be shown as NULL
LEFT JOIN avatar_avatar av
ON av.user_id = u.id
WHERE
ss.seasonid = 1025 ;
如果更多表的内容是可选,则可能需要多个LEFT JOIN
。为了找出有意义的东西,我们需要拥有代表您的场景的完整数据模型或ERD。也就是说,哪些关系是1到1,它们是1到多,它们是1到(0或1),它们是多对多等等。