【问题标题】:how sql join works on 3 tables with examplesql join 如何在 3 个表上使用示例
【发布时间】:2015-09-24 17:52:02
【问题描述】:

我是 sql 连接的新手。谁能用一个简单的例子来解释一下左/右/外连接在连接 3 个表方面是如何工作的?

假设我有以下表格 面积

Area ID PersonID
1        11
2        12
3        13

疾病

DiseaseID   Disease Name
4            ABC
5            DEF

攻击

AttackID    Disease ID  AreaID
111            4          1
222            4          2
222            5          1

我想知道被攻击和未被疾病攻击的人数。

【问题讨论】:

标签: mysql oracle


【解决方案1】:

希望它能满足你的要求

SELECT R.AREA_ID,
       COUNT(A.DISEASEID) ATTACKED_PEOPLE
  FROM AREA R
  LEFT JOIN ATTACK A
    ON A.AREAID=R.AREA_ID
  LEFT JOIN DISEASE D
    ON D.SISEASE_ID=A.DISEASEID
  GROUP BY R.AREA_ID;

这里我们使用了 LEFT JOIN 概念来连接三个表。因此,左侧表 (AREA) 检索所有记录,右侧表 (ATTACK) 仅检索与左侧表匹配的记录。以及第二个 LEFT JOIN 条件是用于从 ATTACK 表中检索疾病计数。这样我们就可以计算出被攻击的人数以及没有使用上述查询的人数。

【讨论】:

    【解决方案2】:

    只有表 AREA 和 ATTACK 包含您需要的信息(您不需要疾病名称), 所以首先将有关攻击的信息附加到包含人员 ID 的表中:

    select personid, count(diseaseid) cnt
      from area left join attack using (areaid)
      group by personid
    
    PersonID  Cnt
          11    2
          13    0
          12    1
    

    现在你可以统计生病和健康的人了:

    select 
        count(case when cnt > 0 then 1 end) Affected,
        count(case when cnt = 0 then 1 end) NotAffected
      from (
        select personid, count(diseaseid) cnt
          from area left join attack using (areaid)
          group by personid)
    
    Affected  NotAffected
           2            1
    

    SQLFiddle demo

    有几种方法可以获得最后的输出,尝试找到其他的。以及如何连接所有三个表的示例:

    select personid, count(diseaseid) cnt, 
        listagg(DiseaseName, ', ') within group (order by DiseaseName) Diseases
      from area 
      left join attack using (areaid)
      left join disease using (diseaseid)
      group by personid
    
    PERSONID   CNT  DISEASES
    --------  ----  ----------
          11     2  ABC, DEF
          12     1  ABC
          13     0
    

    如果您只想查找受影响的人,请使用INNER JOIN 而不是LEFT

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 2015-10-26
      • 2020-09-15
      • 2016-10-14
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多