使用INNER JOIN对GROUP BY中的单独WHERE子句求和

时间:2017-06-24 18:19:41

标签: mysql sql group-by inner-join

我有两个mysql表,一个包含医院列表,另一个包含指标列表。我试图通过在医院表上执行GROUP BY和使用度量表执行INNER JOIN来计算状态范围的汇总统计信息。我在摘要表中寻找多个条件来总结。这就是我的数据库和查询现在的样子......

# create the hospital table and add 4 hospitals from 2 states
CREATE TABLE IF NOT EXISTS hospital (
    hospital_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255),
    state VARCHAR(2),
    PRIMARY KEY (hospital_id)
);
INSERT INTO hospital (name, state)
VALUES ('A', 'AL'), ('B', 'AL'), ('C', 'AK'), ('D', 'AK');


# create metrics table and add 2 metrics per hospital
CREATE TABLE IF NOT EXISTS metric (
    metric_id INT NOT NULL AUTO_INCREMENT,
    hospital VARCHAR(255),
    name VARCHAR(255),
    value INT,
    PRIMARY KEY (metric_id)
);
INSERT INTO metric (hospital, name, value)
VALUES ('A', 'total male patients', 100),
       ('A', 'total female patients', 110),
       ('B', 'total male patients', 55),
       ('B', 'total female patients', 50),
       ('C', 'total male patients', 10),
       ('C', 'total female patients', 7), 
       ('D', 'total male patients', 200),
       ('D', 'total female patients', 170);

# compute statewide metrics
SELECT
    hospital.state,
    metric.name,
    SUM(metric.value) as total
FROM
    hospital
INNER JOIN
    metric
ON
    hospital.name = metric.hospital
WHERE
    (metric.name = 'total male patients' OR metric.name = 'total female patients')
GROUP BY
    hospital.state,
    metric.name;

这是输出......

+-------+-----------------------+-------+
| state | name                  | total |
+-------+-----------------------+-------+
| AK    | total female patients |   177 |
| AK    | total male patients   |   210 |
| AL    | total female patients |   160 |
| AL    | total male patients   |   155 |
+-------+-----------------------+-------+

有没有办法重构我的查询,以便每个状态只获得一行,每个条件只获得一列。例如......

+-------+---------------------+-----------------------+
| state | total male patients | total female patients |
+-------+---------------------+-----------------------+
| AK    | 210                 |       177             |
| AL    | 155                 |       160             |
+-------+---------------------+-----------------------+

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用条件聚合:

SELECT h.state,
       SUM(CASE WHEN m.name = 'total male patients'
                THEN m.value ELSE 0
           END) AS total_male,
       SUM(CASE WHEN m.name = 'total female patients'
                THEN m.value ELSE 0
           END) AS total_female
FROM hospital h INNER JOIN
     metric m
     ON h.name = m.hospital
GROUP BY h.state

请注意,我添加了表别名。我对有意义的列名进行了限定。如果查询中有多个表,则应该限定所有列名。

答案 1 :(得分:1)

你可以使用一个案例来选择2列中的值

  SELECT
      state,
      Item,
      SUM(case when item = 'Total Veterans served' then Value else 0 end ) as total_Veterans_served, 
      SUM(case when item = 'N with PTSD'  then Value else 0 end ) as total_N_with_PTSD, 
  FROM va_location
  INNER JOIN patient_2015 ON va_location.facility_id = patient_2015.Location
  WHERE Category = 'Station-Level Stats'
  AND ValueType = 'Number'
  AND   (Item = 'Total Veterans served' OR Item = 'N with PTSD')
  GROUP BY
      state,
      Item