Search code examples
sqloracleunionunion-all

SQL Merge rows instead of UNION ALL


I'm doing a UNION ALL to get the results as shows in the table below. This approach is causing to have unnecessary rows. The three columns DESK, SEGMENT and SUPERVISOR are independent and have no relationship.

Code

SELECT ID, DESK, '' as SEGMENT, '' as SUPERVISOR FROM myTable1 
UNION ALL 
SELECT ID, '' AS DESK, SEGMENT, '' as SUPERVISOR FROM myTable2 
UNION ALL 
SELECT ID, '' AS DESK, '' as SEGMENT, SUPERVISOR FROM myTable3 

Result:

+------+------------+---------+------------+
| ID   | DESK       | SEGMENT | SUPERVISOR | TOTAL ENTRIES
+------+------------+---------+------------+
| 4782 | OIL & GAS  |         |            |  23
+------+------------+---------+------------+
| 4782 | AUTOMOTIVE |         |            |  23
+------+------------+---------+------------+
| 4782 |            | GLOBAL  |            |  23
+------+------------+---------+------------+
| 4782 |            |         | DANIEL     |  23
+------+------------+---------+------------+
| 4782 |            |         | JAMES      |  23
+------+------------+---------+------------+

How can I query to get the below result?

Expected Result:

+------+------------+---------+------------+
| ID   | DESK       | SEGMENT | SUPERVISOR | TOTAL ENTRIES
+------+------------+---------+------------+
| 4782 | OIL & GAS  | GLOBAL  | DANIEL     |  23
+------+------------+---------+------------+
| 4782 | AUTOMOTIVE |         | JAMES      |  23
+------+------------+---------+------------+

Solution

  • You can use ROW_NUMBER() analytic function with partitioned by ID column along with FULL OUTER JOIN for those three tables like this :

    SELECT NVL(NVL(t2.ID,t3.ID),t1.ID) AS ID, desk, segment, supervisor 
      FROM ( SELECT t1.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn FROM myTable1 t1 ) t1
      FULL JOIN ( SELECT t2.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn FROM myTable2 t2 ) t2
        ON t2.ID = t1.ID AND t2.rn = t1.rn
      FULL JOIN ( SELECT t3.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn FROM myTable3 t3 ) t3
        ON t3.ID = t1.ID AND t3.rn = t1.rn;
    
    
    ID   DESK        SEGMENT  SUPERVISOR
    ---- ----------  -------  ----------
    4782 AUTOMOTIVE  GLOBAL   JAMES
    4782 OIL & GAS            DANIEL  
    

    Demo

    P.S: I left ORDER BY 0 as ORDER BY option is mandatory for ROW_NUMBER(), you can replace zero with a proper column or identifier for you.