与使用单个内部联接相比,使用多个内部联接时我得到不同的结果
When using multiple inner joins I get different results compared to when I use a single inner join
我无法理解为什么我的两个 SQL 查询输出了不同的高级管理人员计数结果,而我预计它们是相同的。
SELECT COMPANY.Company_Code, COMPANY.Founder, COUNT(SENIOR_MANAGER.Senior_Manager_Code)
FROM COMPANY INNER JOIN SENIOR_MANAGER
ON SENIOR_MANAGER.COMPANY_CODE = COMPANY.COMPANY_CODE
GROUP BY COMPANY.COMPANY_CODE, COMPANY.FOUNDER;
这个SQL查询试图找出不同公司有多少高级经理,结果如下:
C1 Angela 5
C10 Earl 2
C100 Aaron 4
C11 Robert 1
C12 Amy 6
但是,当我在使用两个内部联接的另一个查询中使用相同的条件时,我得到了另一组结果。这是我的查询:
SELECT COMPANY.COMPANY_CODE, COMPANY.FOUNDER, COUNT(LEAD_MANAGER.LEAD_MANAGER_CODE),
COUNT(SENIOR_MANAGER.SENIOR_MANAGER_CODE)
FROM COMPANY INNER JOIN LEAD_MANAGER
ON COMPANY.COMPANY_CODE = LEAD_MANAGER.COMPANY_CODE
INNER JOIN SENIOR_MANAGER
ON SENIOR_MANAGER.COMPANY_CODE = COMPANY.COMPANY_CODE
GROUP BY COMPANY.COMPANY_CODE, COMPANY.FOUNDER;
结果如下:
C1 Angela 10 10
C10 Earl 2 2
C100 Aaron 8 8
C11 Robert 1 1
C12 Amy 12 12
第四列是高级管理人员的数量,由于某种原因与第三列的值相同,但与我显示的第一个查询的值不同。有人可以解释为什么结果不同吗?我怀疑这可能是因为我错误地使用了内部联接?
我期望的结果是第四列显示第一个查询的值。
每次加入新的table,结果集中的每一行都乘以该行在新的table中匹配加入条件的次数。
所以你的结果显示 C1、C100 和 C12 中的每一个都有两个 LEAD_MANAGERs。
由于双连接查询的计数反映了单连接查询的倍数,因此您重复计算了以前与新连接不同的配对。
具体来说,在第一个查询中,COMPANY
和 SENIOR_MANAGER
table 可以具有一对多关系,其中一个不同的公司可以有多个高级经理。
然而,在第二个查询中,当包含 LEAD_MANAGER
table 时,它与 COMPANY
有更多不同的配对,您为每个对应的配对重复 SENIOR_MANAGER
多次COMPANY
和 LEAD_MANAGER
.
作为重复计算的解决方案,考虑加入聚合子查询(或CTEs):
SELECT agg_s.COMPANY_CODE,
agg_s.FOUNDER,
agg_s.SENIOR_MANAGER_COUNT.
agg_l.LEAD_MANAGER_COUNT
FROM
(SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(s.SENIOR_MANAGER_CODE) AS SENIOR_MANAGER_COUNT
FROM COMPANY c
INNER JOIN SENIOR_MANAGER s
ON s.COMPANY_CODE = c.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER
) AS agg_s
INNER JOIN
(SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(l.LEAD_MANAGER_CODE) AS LEAD_MANAGER_COUNT
FROM COMPANY c
INNER JOIN LEAD_MANAGER l
ON c.COMPANY_CODE = l.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER
) AS agg_l
ON agg_s.COMPANY_CODE = agg_l.COMPANY_CODE
AND agg_s.FOUNDER = agg_l.FOUNDER
更好的是,考虑 table 设计更改以实现适当的规范化,您可以在其中维护 单个 MANAGER
table 和 TYPE
SENIOR
或 LEAD
的指示符列。然后运行一个单个条件聚合查询:
SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(CASE WHEN m.TYPE = 'SENIOR' THEN 1 ELSE NULL END) AS SENIOR_MANAGER_COUNT,
COUNT(CASE WHEN m.TYPE = 'LEAD' THEN 1 ELSE NULL END) AS LEAD_MANAGER_COUNT
FROM COMPANY c
INNER JOIN MANAGER m
ON c.COMPANY_CODE = m.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER;
我无法理解为什么我的两个 SQL 查询输出了不同的高级管理人员计数结果,而我预计它们是相同的。
SELECT COMPANY.Company_Code, COMPANY.Founder, COUNT(SENIOR_MANAGER.Senior_Manager_Code)
FROM COMPANY INNER JOIN SENIOR_MANAGER
ON SENIOR_MANAGER.COMPANY_CODE = COMPANY.COMPANY_CODE
GROUP BY COMPANY.COMPANY_CODE, COMPANY.FOUNDER;
这个SQL查询试图找出不同公司有多少高级经理,结果如下:
C1 Angela 5
C10 Earl 2
C100 Aaron 4
C11 Robert 1
C12 Amy 6
但是,当我在使用两个内部联接的另一个查询中使用相同的条件时,我得到了另一组结果。这是我的查询:
SELECT COMPANY.COMPANY_CODE, COMPANY.FOUNDER, COUNT(LEAD_MANAGER.LEAD_MANAGER_CODE),
COUNT(SENIOR_MANAGER.SENIOR_MANAGER_CODE)
FROM COMPANY INNER JOIN LEAD_MANAGER
ON COMPANY.COMPANY_CODE = LEAD_MANAGER.COMPANY_CODE
INNER JOIN SENIOR_MANAGER
ON SENIOR_MANAGER.COMPANY_CODE = COMPANY.COMPANY_CODE
GROUP BY COMPANY.COMPANY_CODE, COMPANY.FOUNDER;
结果如下:
C1 Angela 10 10
C10 Earl 2 2
C100 Aaron 8 8
C11 Robert 1 1
C12 Amy 12 12
第四列是高级管理人员的数量,由于某种原因与第三列的值相同,但与我显示的第一个查询的值不同。有人可以解释为什么结果不同吗?我怀疑这可能是因为我错误地使用了内部联接?
我期望的结果是第四列显示第一个查询的值。
每次加入新的table,结果集中的每一行都乘以该行在新的table中匹配加入条件的次数。
所以你的结果显示 C1、C100 和 C12 中的每一个都有两个 LEAD_MANAGERs。
由于双连接查询的计数反映了单连接查询的倍数,因此您重复计算了以前与新连接不同的配对。
具体来说,在第一个查询中,COMPANY
和 SENIOR_MANAGER
table 可以具有一对多关系,其中一个不同的公司可以有多个高级经理。
然而,在第二个查询中,当包含 LEAD_MANAGER
table 时,它与 COMPANY
有更多不同的配对,您为每个对应的配对重复 SENIOR_MANAGER
多次COMPANY
和 LEAD_MANAGER
.
作为重复计算的解决方案,考虑加入聚合子查询(或CTEs):
SELECT agg_s.COMPANY_CODE,
agg_s.FOUNDER,
agg_s.SENIOR_MANAGER_COUNT.
agg_l.LEAD_MANAGER_COUNT
FROM
(SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(s.SENIOR_MANAGER_CODE) AS SENIOR_MANAGER_COUNT
FROM COMPANY c
INNER JOIN SENIOR_MANAGER s
ON s.COMPANY_CODE = c.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER
) AS agg_s
INNER JOIN
(SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(l.LEAD_MANAGER_CODE) AS LEAD_MANAGER_COUNT
FROM COMPANY c
INNER JOIN LEAD_MANAGER l
ON c.COMPANY_CODE = l.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER
) AS agg_l
ON agg_s.COMPANY_CODE = agg_l.COMPANY_CODE
AND agg_s.FOUNDER = agg_l.FOUNDER
更好的是,考虑 table 设计更改以实现适当的规范化,您可以在其中维护 单个 MANAGER
table 和 TYPE
SENIOR
或 LEAD
的指示符列。然后运行一个单个条件聚合查询:
SELECT c.COMPANY_CODE,
c.FOUNDER,
COUNT(CASE WHEN m.TYPE = 'SENIOR' THEN 1 ELSE NULL END) AS SENIOR_MANAGER_COUNT,
COUNT(CASE WHEN m.TYPE = 'LEAD' THEN 1 ELSE NULL END) AS LEAD_MANAGER_COUNT
FROM COMPANY c
INNER JOIN MANAGER m
ON c.COMPANY_CODE = m.COMPANY_CODE
GROUP BY c.COMPANY_CODE,
c.FOUNDER;