MySQL查询中的2个LEFT JOIN

时间:2018-04-13 15:06:20

标签: mysql

我试图在表格中列出所有比赛,用户是否已参加每场比赛,以及每场比赛的参赛作品总数。

以下是表格:

CREATE TABLE `competition` (
`competitionID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` char(255) NOT NULL DEFAULT '',
`description` varchar(750) NOT NULL DEFAULT '',
`startDate` date DEFAULT NULL,
`endDate` date DEFAULT NULL,
`isLive` tinyint(1) NOT NULL,
PRIMARY KEY (`competitionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `competition` (`competitionID`, `name`, `description`, 
`startDate`, `endDate`, `isLive`)
VALUES
(1,'Win a car','Win a really cool car!','2018-04-01 09:30:27','2019-04-01 09:30:27',1),
(2,'Another competition','Win something even better!','2018-04-01 09:30:27','2019-04-01 09:30:27',1);

CREATE TABLE `competition_entrant` (
`competitionEntrantID` int(11) NOT NULL AUTO_INCREMENT,
`userID` int(11) NOT NULL,
`competitionID` int(11) NOT NULL,
PRIMARY KEY (`competitionEntrantID`),
UNIQUE KEY `userID` (`userID`,`competitionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `competition_entrant` (`competitionEntrantID`, `userID`, 
`competitionID`)
VALUES
(1,1,1),
(2,1,2),
(3,2,1);

因此,在此示例中,id为1的用户已进入两场比赛,而id为2的用户已与id 1进行比赛。

这是我的查询。

SELECT
`c`.`name`,
COUNT(`ce1`.`userID`) AS 'hasEnteredCompetition',
COUNT(`ce2`.`userID`) AS 'totalEntries'
FROM competition c
LEFT JOIN `competition_entrant` `ce1` ON `c`.`competitionID` = 
`ce1`.`competitionID`
AND `ce1`.`userID` = 2
LEFT JOIN `competition_entrant` `ce2` ON `c`.`competitionID` = 
`ce2`.`competitionID`
GROUP BY (c.competitionID);

问题在于hasEnteredCompetition显示的是条目总数,而不是仅为输入的用户输入1,即该用户的计数。

谁能告诉我这里我做错了什么?

2 个答案:

答案 0 :(得分:1)

您正在两次加入competition_entrant表,因此用户“2”条目被拉两次。你可以这样看:

SELECT C.COMPETITIONID,C.NAME,CE1.USERID,CE1.COMPETITIONID
FROM COMPETITION C
LEFT JOIN COMPETITION_ENTRANT CE1 ON C.COMPETITIONID = CE1.COMPETITIONID AND CE1.USERID = 2
LEFT JOIN COMPETITION_ENTRANT CE2 ON C.COMPETITIONID = CE2.COMPETITIONID


1   Win a car           2       1
2   Another competition null    null        
1   Win a car           2       1

您可以像这样添加一个与您的查询不同的计数:

select C.NAME,C.COMPETITIONID,
COUNT(DISTINCT CE1.USERID) as "hasEnteredCompetition",
COUNT(CE2.USERID) as "totalEntries"
from COMPETITION C
left join COMPETITION_ENTRANT CE1 on C.COMPETITIONID = CE1.COMPETITIONIDand CE1.USERID = 2
left join COMPETITION_ENTRANT CE2 on C.COMPETITIONID = CE2.COMPETITIONID
group by (C.NAME,C.COMPETITIONID)

答案 1 :(得分:1)

如果我理解正确("预期结果"会很好),您只需要列出所有比赛,输入的用户数量以及是否有人输入,对吗?然后你不需要第二个左连接,你可以使用这样的东西:

select 
    competition.competitionID, 
    competition.name,
    case when count(competition.competitionID) > 0 THEN 'yes' ELSE 'no' END AS hasEnteredCompetition,
    count(competition.competitionID) AS 'totalEntries'
from competition
left join competition_entrant ON competition.competitionID = competition_entrant.competitionID
group by competitionId, name