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

时间:2009-01-22 21:56:17

标签: sql

数据库结构:

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。

报告应该是:播放器名称,俱乐部名称,Start_date,End_date

3 个答案:

答案 0 :(得分:4)

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

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,因此对于GROUP BY子句中的select-list不匹配列中的列,您可以非常灵活。其他品牌的RDBMS对单值规则更严格。

没有理由像你的例子那样使用LEFT JOIN。


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

您有以下关系链:

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;

答案 1 :(得分:0)

以下是一个赛季的球员名单。

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。

答案 2 :(得分:0)

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