使用右表上的总和分组对多列进行 SQL 连接

Posted

技术标签:

【中文标题】使用右表上的总和分组对多列进行 SQL 连接【英文标题】:SQL join on multiple columns using grouped by sum on right table 【发布时间】:2014-09-30 10:40:43 【问题描述】:

我有两个表(表 A 和表 B),我想加入多个列。 但是连接的第三个条件是表 B 上的值的总和。

表 A

Col1     Col2     Col3
=======================
AX1      AY1       1          
AX1      AY2       7       
AX1      AY3       9          
AX2      AY1       1          

表 B

Col1     Col2     Col3
=======================  
BX1      BY1       0,5          
BX1      BY1       0,5          
BX1      BY2       3       
BX1      BY2       3                 
BX2      BY1       1      

所以目的是加入

    A.col1 = B.Col1 
    AND A.Col2 = B.Col2 
    AND A.Col3 = sum(B.Col3)
GROUP BY 
   B.Col1, B.Col2

为了使事情更容易,最终目的是排除表 A 和 B 之间的匹配。因此,最终结果将是表 A 中的记录,其中总和在表 B 中不匹配,并显示两者的值表。 (也就是说,集合 A 加入集合 B 排除公共集合)

表格结果

Col1     Col2     A.Col3   B.Col3
=================================
X1       Y2        7        6       
X1       Y3        9        null  

我尝试了多个完全外连接,只使用空键,但从未设法得到正确的结果。我通常只从表中获取 X1-Y2 值,而不是 X1-Y3。

谢谢!

尼克贝

【问题讨论】:

【参考方案1】:

试试这个:

SELECT A.*, B.col3_sum
 FROM A
 LEFT JOIN (
  SELECT Col1, Col2, SUM(Col3) col3_sum
   FROM B
   GROUP BY Col1, Col2
 ) B ON A.Col1 = B.Col1 
    AND A.Col2 = B.Col2 
 WHERE B.col3_sum IS NULL
    OR B.col3_sum <> A.Col3

测试一下:http://sqlfiddle.com/#!2/23fb77/3

【讨论】:

【参考方案2】:

试试这个(没有真正测试过),也许有更简单的解决方案:

SELECT NVL(a.col1, b.col1),
       NVL(a.col2, b.col2),
       MAX(a.col3) AS a_col3,
       MAX(b.col3) AS b_col3
  FROM ta a
  FULL
 OUTER 
  JOIN(SELECT col1,
              col2,
              SUM(col3) AS col3
         FROM tb
        GROUP
           BY col1,
              col2
      ) b
    ON a.col1 = b.col1
   AND a.col2 = b.col2
   AND a.col3 = b.col3
 WHERE b.col3 IS NULL OR a.col3 IS NULL 
 GROUP
    BY NVL(a.col1, b.col1),
       NVL(a.col2, b.col2)

【讨论】:

【参考方案3】:

感谢@Rimas 和@DirkNM,两种解决方案都返回了正确的结果!

Rimas 的解决方案在执行时更快(并且更易于阅读)

COL1 COL2           COL3   COL3_SUM
---- -------- ---------- ----------
X1   20140202          7          6 
X1   20140303          9            


NVL(A.COL1,B.COL1) NVL(A.COL2,B.COL2)     A_COL3     B_COL3
------------------ ------------------ ---------- ----------
X1                 20140303                    9            
X1                 20140202                    7          6 

【讨论】:

以上是关于使用右表上的总和分组对多列进行 SQL 连接的主要内容,如果未能解决你的问题,请参考以下文章

优化大型表上的 SQL 连接

在两个表上分组并在结果VBA ADODB SQL查询上执行左连接

删除左表上的重复项,同时在右表SELECT JOIN上保留重复项

根据两个不同表上的两列对完全连接进行排序

在两个索引表上使用组和连接进行单独 LINQ2SQL 选择与一个组合选择的性能

使用 2GB+ 加速单个表上的 SQL 查询