简体   繁体   中英

How to SUM rows with an outer join?

Question:

I have the following tables that I'd like to sum on two fields: HOURS and RATE. I also want to retrieve the NAME from the third table, joining all 3 tables on the field LINE_NUM.

If the LINE_NUM and CODE are the same, sum the fields of A with 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 |

The result I'm looking for should be:

| 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 |

Any idea how I can achieve this?


What I tried:

I've tried (table A with C) UNION (table B with C), but I can't get the sums to work.

  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

But I couldn't get the sum to work and it returned:

| 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 |

Your approach wasn't bad and you were almost there.

You should make the GROUP BY on the results of the 2 UNIONed queries being nested:

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

However this will return wrong results because the JOINs on the PAYCHECK table will returns duplicates.

There's obviously something missing somewhere.

To identify the employee, you should combine 2 columns : EMPLOYEE_ID and LINE_NUM . For the first query on EARNING, there's no issue as the EMPLOYEE_ID is present in the table. However for the second query on OTH_EARNINGS , the EMPLOYEE_ID is missing...

In theory you should have something like this (check the 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

I also changed from your initial query:

  1. the JOINs from implicit to explicit syntax.

  2. the UNION into an UNION ALL as there's no reason here to remove the duplicates (maybe I am wrong)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM