繁体   English   中英

如何创建SQL查询以获取另一列的每个GROUP'ed BY值的列的唯一值

[英]How to create SQL query to get unique values of column for each GROUP'ed BY value of another column

首先,很抱歉我的问题名称令人困惑,我不知道如何正确提出。

我将展示我正在尝试做的例子。 假设我们有3个表:数据库中的“足球运动员”,“团队”和“得分”(我使用MySQL 5.5作为DBMS)。 它们非常简单:

CREATE TABLE footballer (
  fb_pk      INT(8) NOT NULL AUTO_INCREMENT,
  first_name CHAR(40),
  last_name  CHAR(40),
  PRIMARY KEY (fb_pk)
);

CREATE TABLE team (
  team_pk INT(8) NOT NULL AUTO_INCREMENT,
  name    CHAR(40),
  PRIMARY KEY (team_pk)
);

CREATE TABLE score (
  score_pk      INT(8) NOT NULL AUTO_INCREMENT,
  goal_count    INT(3) NOT NULL,
  team_fk       INT(8) NOT NULL,
  fb_fk         INT(8) NOT NULL,
  goal_distance ENUM('LONG', 'SHORT'),
  PRIMARY KEY (score_pk),
  CONSTRAINT fk_team FOREIGN KEY (team_fk) REFERENCES team (team_pk),
  CONSTRAINT fk_footballer FOREIGN KEY (fb_fk) REFERENCES footballer (fb_pk)
);

“得分”表存储有关球队和足球运动员制定的目标的信息,其中:

“ goal_count”-是达成的许多目标,

'team_fk'-是团队的外键,

'fb_fk'-是足球运动员的外键,

“ goal_distance”-是达成(长或短)目标的一种。

表中有以下数据:

INSERT INTO footballer (first_name, last_name)
VALUES
  ('Footballer', 'One'),
  ('Footballer', 'Two'),
  ('Footballer', 'Three'),
  ('Footballer', 'Four'),
  ('Footballer', 'Five');

INSERT INTO team (name)
VALUES
  ('Team 1'),
  ('Team 2'),
  ('Team 3');

INSERT INTO score (goal_count, team_fk, fb_fk, goal_distance)
VALUES
  (2, 1, 1, 'SHORT'), -- Two goals | by team #1 | by player #1 | short goal
  (3, 1, 1, 'LONG'),
  (1, 1, 2, 'SHORT'),
  (1, 2, 1, 'SHORT'),
  (2, 2, 2, 'SHORT'),
  (2, 2, 4, 'LONG');

(2,1,1,'SHORT')行表示玩家1从团队1取得了2个短期进球。

现在,我想收集“得分”表的统计数据:每个团队制定了多少个短/长/总目标,以及每个团队中有多少个球员制定了目标 这是我的评论评论:

SELECT
  -- Team name
  t.name,
  -- How much short goals
  (
    SELECT
      SUM(s1.goal_count)
    FROM score s1
    WHERE s1.team_fk = s.team_fk AND s1.goal_distance = 'SHORT'
  ) short_count,
  -- How much long goals
  (
    SELECT
      SUM(s1.goal_count)
    FROM score s1
    WHERE s1.team_fk = s.team_fk AND s1.goal_distance = 'LONG'
  ) long_count,
  -- Total goals
  (SELECT short_count + long_count) total,
  -- How much players made goals
  (
    SELECT COUNT(*)
    FROM (
      SELECT DISTINCT
        team_fk, fb_fk
      FROM score
    ) s1
    WHERE s1.team_fk = s.team_fk
  ) goal_player_count
FROM score s
INNER JOIN team t
  ON s.team_fk = t.team_pk
GROUP BY s.team_fk;

查询返回以下结果: 结果

它可以按预期工作,但是我认为有一种更好的方法来获取“ 制定目标的每个团队中的球员 ”的数量。

为了更清楚地说明如何计算该值,下面是一个示例:

团队#1的“得分”表中有3行:

(2, 1, 1, 'SHORT'),
(3, 1, 1, 'LONG'),
(1, 1, 2, 'SHORT'),

玩家1进了2个短球,

玩家1取得3个长球,

玩家2进了1个短球。

总共有2位球员为此团队进球(球员1和球员2)。

当前,这种查询的和平性负责计算该值:

(
    SELECT COUNT(*)
    FROM (
      SELECT DISTINCT
        team_fk, fb_fk
      FROM score
    ) s1
    WHERE s1.team_fk = s.team_fk
) goal_player_count

也许还有另一种(更好)的方法可以达到相同的结果? 因为这部分查询对我来说很难看/不寻常(SELECT内的SELECT内的SELECT)。

我认为您可以通过更小的查询来获取所需的信息:

  SELECT t.name,
         SUM((s.goal_distance = 'SHORT') * s.goal_count) short_count,
         SUM((s.goal_distance = 'LONG')  * s.goal_count) long_count,
         SUM(s.goal_count) total,
         COUNT(DISTINCT f.fb_pk) goal_player_count
    FROM team t
    JOIN score s
      ON s.team_fk = t.team_pk
    JOIN footballer f
      ON f.fb_pk = s.fb_fk
GROUP BY t.team_pk 

SQLFiddle演示

这利用了一个事实,即在MySQL中进行比较,例如s.goal_distance = 'SHORT'将为false返回0 ,为true(或NULL )返回1 ,从而允许在不同条件下进行计数。 在这种情况下, COUNT()DISTINCT选项也很有用。

我很惊讶您选择不将每个目标记录在单独的元组中。 这将允许记录单个统计信息(例如目标时间),而无需为此查询增加太多工作量,并且可以提供更加灵活的报告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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