如何计算SQL中不同项目的数量

如何计算SQL中不同项目的数量,sql,Sql,数据库结构: Clubs: ID, ClubName Teams: ID, TeamName, ClubID Players: ID, Name Registrations: PlayerID, TeamID, Start_date, End_date, SeasonID 俱乐部拥有几支球队。球员可以在一年内注册到同一俱乐部或不同俱乐部的多支球队。 我必须生成一个查询,列出在一个赛季中注册到不同俱乐部的所有球员。所以,如果球员交换了属于同一俱乐部的球队,那就不算了 我迄今为止的努力: SELE

数据库结构:

Clubs: ID, ClubName
Teams: ID, TeamName, ClubID
Players: ID, Name
Registrations: PlayerID, TeamID, Start_date, End_date, SeasonID
俱乐部拥有几支球队。球员可以在一年内注册到同一俱乐部或不同俱乐部的多支球队。 我必须生成一个查询,列出在一个赛季中注册到不同俱乐部的所有球员。所以,如果球员交换了属于同一俱乐部的球队,那就不算了

我迄今为止的努力:

SELECT
c.short_name,
p.surname,
r.start_date,
r.end_date,
(select count(r2.id) from ejl_registration as r2
    where r2.player_id=r.player_id and r2.season=r.season) as counter
FROM
ejl_registration AS r
left Join ejl_players AS p ON p.id = r.player_id
left Join ejl_teams AS t ON r.team_id = t.id
left Join ejl_clubs AS c ON t.club_id = c.id
WHERE
r.season =  '2008'
having counter >1
我不知道如何计数和显示不同的俱乐部。。。现在想清楚已经太晚了。我使用MySQL


报告应该是这样的:球员姓名、俱乐部名称、开始日期、结束日期这是一个赛季的球员名单

SELECT sub.PlayerId
FROM
(
  SELECT
    r.PlayerId,
    (SELECT t.ClubID FROM Teams t WHERE r.TeamID = t.ID) as ClubID
  FROM Registrations r
  WHERE r.Season = '2008'
) as sub
GROUP BY PlayerId
HAVING COUNT(DISTINCT sub.ClubID) > 1
这是所有赛季的球员和赛季列表

SELECT PlayerId, Season
FROM
(
SELECT
  r.PlayerId,
  r.Season,
  (SELECT t.ClubID FROM Teams t WHERE r.TeamID = t.ID) as ClubID
FROM Registrations r
) as sub
GROUP BY PlayerId, Season
HAVING COUNT(DISTINCT sub.ClubID) > 1

顺便说一句,这在MS SQL中有效。

这是对这个答案的第二次尝试,将其简化为只计算不同的俱乐部,而不报告俱乐部名称列表

SELECT p.surname, r.start_date, r.end_date, COUNT(DISTINCT c.id) AS counter
FROM ejl_players p
 JOIN ejl_registration r ON (r.player_id = p.id)
 JOIN ejl_teams t ON (r.team_id = t.id)
 JOIN ejl_clubs c ON (t.club_id = c.id)
WHERE r.season = '2008'
GROUP BY p.id
HAVING counter > 1;
请注意,因为您使用的是MySQL,所以对于select列表中的列与GROUPBY子句中的列不匹配的情况,您可以非常灵活。其他品牌的RDBMS对单值规则更为严格

没有理由像您的示例中那样使用左连接

好的,这是查询的第一个版本:

您有一系列关系,如下所示:

club1 <-- team1 <-- reg1 --> player <-- reg2 --> team2 --> club2
这样club1就不能与club2相同

SELECT p.surname,
  CONCAT_WS(',', GROUP_CONCAT(DISTINCT t1.team_name), 
    GROUP_CONCAT(DISTINCT t2.team_name)) AS teams,
  CONCAT_WS(',', GROUP_CONCAT(DISTINCT c1.short_name), 
    GROUP_CONCAT(DISTINCT c2.short_name)) AS clubs
FROM ejl_players p
 -- Find a club where this player is registered
 JOIN ejl_registration r1 ON (r1.player_id = p.id)
 JOIN ejl_teams t1 ON (r1.team_id = t1.id)
 JOIN ejl_clubs c1 ON (t1.club_id = c1.id)
 -- Now find another club where this player is registered in the same season
 JOIN ejl_registration r2 ON (r2.player_id = p.id AND r1.season = r2.season)
 JOIN ejl_teams t2 ON (r2.team_id = t2.id)
 JOIN ejl_clubs c2 ON (t2.club_id = c2.id)
-- But the two clubs must not be the same (use < to prevent duplicates)
WHERE c1.id < c2.id
GROUP BY p.id;

“AS sub”表表达式中的相关子选择有点笨拙;为什么不使用加入?婚前加入是违反我的宗教的。这将作为一个加入,因为没有任何球队有超过1个俱乐部。。。另外,MS Sql不关心您以何种方式表达这一点,这将显示左派加入执行计划。很有趣,但它回答了一个相当复杂的问题:列出在一个赛季中在两个或更多俱乐部注册的球员,并包括每个球员和每对不同俱乐部的俱乐部和球队详细信息。你不必简化它-俱乐部列表需要名字。我已经恢复了第一个答案并粘贴在上面。谢谢!不幸的是,我不能给你超过+1。似乎这个查询只适用于2个俱乐部。当用户在Club1team1->Club1team2->Club2team3中跳转时,我会列出4个名称:Club1、Club1、Club2、Club2。当他跳出Club1->Club2->Club3时,重复的结果会变得更长,这只是列出了球员。就连我的提问也做到了。
SELECT p.Name, x.PlayerID, x.SeasonID
  FROM (SELECT DISTINCT r.PlayerID, r.SeasonID, t.ClubID
          FROM Registrations r
          JOIN Teams t ON t.ID = r.TeamID) x
  JOIN Players p ON p.ID = x.PlayerID
 GROUP BY p.rName, x.PlayerID, x.SeasonID
HAVING COUNT(*) > 1