【问题标题】:How to SUM rows with an outer join?如何对具有外连接的行求和?
【发布时间】:2017-08-02 00:54:31
【问题描述】:

问题:

我想对以下两个字段进行汇总:HOURS 和 RATE。我还想从第三个表中检索 NAME,加入字段 LINE_NUM 上的所有 3 个表。

如果LINE_NUM和CODE相同,则将A和B的字段相加。

Table EARNINGS A:

| EMPLOYEE_ID | LINE_NUM | REG_CODE | REG_HOURS | REG_RATE |
------------------------------------------------------------
| 0001        | 1        | C        | 20        | 200      |
| 0002        | 1        | H        | 0         | 0        |


Table OTH_EARNINGS B:

| LINE_NUM | OTH_CODE | OTH_HOURS | OTH_RATE |
----------------------------------------------
| 1        | A        | 0         | 0        |
| 1        | B        | 0         | 0        |
| 1        | C        | 10        | 100      |
| 2        | A        | 50        | 50       |


Table PAYCHECK C:

| EMPLOYEE_ID | LINE_NUM | NAME |
---------------------------------
| 0001        | 1        | Tom  |
| 0001        | 2        | Tom  |
| 0002        | 1        | John |

我要找的结果应该是:

| EMPLOYEE_ID | LINE_NUM | CODE | HOURS | RATE | NAME |
-------------------------------------------------------
| 0001        | 1        | A    | 0     | 0    | Tom  |
| 0001        | 1        | B    | 0     | 0    | Tom  |
| 0001        | 1        | C    | 30    | 300  | Tom  |
| 0001        | 2        | A    | 50    | 50   | Tom  |
| 0002        | 1        | H    | 0     | 0    | John |

知道如何实现这一目标吗?


我尝试了什么:

我已经尝试过(表 A 和 C)UNION(表 B 和 C),但我无法计算总和。

  SELECT C.EMPLOYEE_ID, A.REG_CODE, A.REG_HRS, SUM(A.REG_RATE) 
  FROM EARNINGS A, PAYCHECK C
  WHERE A.LINE_NUM = C.LINE_NUM
  GROUP BY C.EMPLOYEE_ID, A.REG_CODE, A.REG_HRS
UNION
  SELECT D.EMPLOYEE_ID, B.OTH_CODE, B.OTH_HRS, SUM(B.OTH_RATE) 
  FROM OTH_EARNINGS B, PAYCHECK D
  WHERE B.LINE_NUM = D.LINE_NUM
  GROUP BY D.EMPLOYEE_ID, B.OTH_CODE, B.OTH_HRS

但我无法得到总和,它返回了:

| EMPLOYEE_ID | LINE_NUM | CODE | HOURS | RATE | NAME |
-------------------------------------------------------
| 0001        | 1        | A    | 0     | 0    | Tom  |
| 0001        | 1        | B    | 0     | 0    | Tom  |
| 0001        | 1        | C    | 10    | 100  | Tom  |
| 0001        | 1        | C    | 20    | 200  | Tom  |
| 0001        | 2        | A    | 50    | 50   | Tom  |
| 0002        | 1        | H    | 0     | 0    | John |

【问题讨论】:

    标签: sql oracle outer-join


    【解决方案1】:

    你的方法还不错,你就快到了。

    您应该对嵌套的 2 个 UNIONed 查询的结果进行 GROUP BY:

    SELECT EMPLOYEE_ID, NAME, CODE, SUM(HRS), SUM(RATE)
    FROM
    (  
          SELECT C.EMPLOYEE_ID, C.NAME, A.REG_CODE AS CODE, A.REG_HRS AS HRS, A.REG_RATE AS RATE
          FROM EARNINGS A
          INNER JOIN PAYCHECK C ON A.LINE_NUM = C.LINE_NUM
    
        UNION ALL
    
          SELECT D.EMPLOYEE_ID, C.NAME, B.OTH_CODE AS CODE, B.OTH_HRS AS HRS, B.OTH_RATE AS RATE
          FROM OTH_EARNINGS B 
          INNER JOIN PAYCHECK D ON  B.LINE_NUM = D.LINE_NUM
    )  
    GROUP BY EMPLOYEE_ID, NAME, CODE
    

    但是,这将返回错误的结果,因为 PAYCHECK 表上的 JOIN 将返回重复项。

    显然某处缺少某些东西。

    要识别员工,您应该组合 2 列:EMPLOYEE_IDLINE_NUM。对于 EARNING 的第一个查询,没有问题,因为表中存在 EMPLOYEE_ID。但是对于OTH_EARNINGS 的第二个查询,EMPLOYEE_ID 丢失了...

    理论上你应该有这样的东西(检查 INNER JOIN...ON)

    SELECT EMPLOYEE_ID, NAME, CODE, SUM(HRS), SUM(RATE)
    FROM
    (  
          SELECT C.EMPLOYEE_ID, C.NAME, A.REG_CODE AS CODE, A.REG_HRS AS HRS, A.REG_RATE AS RATE
          FROM EARNINGS A
          INNER JOIN PAYCHECK C ON A.LINE_NUM = C.LINE_NUM AND A.EMPLOYEE_ID = C.EMPLOYEE_ID
    
        UNION ALL
    
          SELECT D.EMPLOYEE_ID, C.NAME, B.OTH_CODE AS CODE, B.OTH_HRS AS HRS, B.OTH_RATE AS RATE
          FROM OTH_EARNINGS B 
          INNER JOIN PAYCHECK D ON  B.LINE_NUM = D.LINE_NUM AND B.EMPLOYEE_ID = D.EMPLOYEE_ID
    )  
    GROUP BY EMPLOYEE_ID, NAME, CODE
    

    我也改变了你最初的查询:

    1. 从隐式到显式语法的 JOIN。

    2. 将 UNION 转换为 UNION ALL,因为这里没有理由删除重复项(也许我错了)

    【讨论】:

      猜你喜欢
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 2020-09-22
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 2011-02-09
      相关资源
      最近更新 更多