问题描述
我正在做UNION ALL
来获得结果,如下表所示。这种方法导致不必要的行。 DESK,SEGMENT和SUPERVISOR这三列是独立的,没有关系。
SELECT ID,DESK,'' as SEGMENT,'' as SUPERVISOR FROM myTable1
UNION ALL
SELECT ID,'' AS DESK,SEGMENT,'' as SUPERVISOR FROM myTable2
UNION ALL
SELECT ID,SUPERVISOR FROM myTable3
结果:
+------+------------+---------+------------+
| ID | DESK | SEGMENT | SUPERVISOR | TOTAL ENTRIES
+------+------------+---------+------------+
| 4782 | OIL & GAS | | | 23
+------+------------+---------+------------+
| 4782 | AUTOMOTIVE | | | 23
+------+------------+---------+------------+
| 4782 | | GLOBAL | | 23
+------+------------+---------+------------+
| 4782 | | | DANIEL | 23
+------+------------+---------+------------+
| 4782 | | | JAMES | 23
+------+------------+---------+------------+
如何查询以获得以下结果?
预期结果:
+------+------------+---------+------------+
| ID | DESK | SEGMENT | SUPERVISOR | TOTAL ENTRIES
+------+------------+---------+------------+
| 4782 | OIL & GAS | GLOBAL | DANIEL | 23
+------+------------+---------+------------+
| 4782 | AUTOMOTIVE | | JAMES | 23
+------+------------+---------+------------+
解决方法
对于这三个表,可以将ROW_NUMBER()
分析函数与ID
一起按FULL OUTER JOIN
列进行分区:
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
P.S:我离开了ORDER BY 0
,因为ORDER BY
必须使用ROW_NUMBER()
选项,您可以用合适的列或标识符替换零。
您可以尝试以下方法:
SELECT table1.ID,table1.DESK,table2.SEGMENT,(select SUPERVISOR from (select SUPERVISOR,ROWNUM AS RN FROM table3) WHERE RN = 1) SUPERVISOR
FROM table1 JOIN table2 on table1.ID = table2.ID
WHERE table1.DESK = 'OIL & GAS'
UNION ALL
SELECT table1.ID,null SEGMENT,ROWNUM AS RN FROM table3) WHERE RN = 2) SUPERVISOR
FROM table1 JOIN table2 on table1.ID = table2.ID
WHERE table1.DESK = 'AUTOMOTIVE'
,https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=c5594bb1d99579611d2669f6bab675a2
您可以尝试以下查询。我不知道23的来源,因此我没有将其计入查询中,但是如果它是三个表之一中的一列,则可以使用类似的逻辑将其添加到结果中。
查询
WITH
table1 (id,desk)
AS
(SELECT 4782,'OIL & GAS' FROM DUAL
UNION ALL
SELECT 4782,'AUTOMOTIVE' FROM DUAL),table2 (id,segment) AS (SELECT 4782,'GLOBAL' FROM DUAL),table3 (id,supervisor)
AS
(SELECT 4782,'DANIEL' FROM DUAL
UNION ALL
SELECT 4782,'JAMES' FROM DUAL)
SELECT *
FROM (SELECT t1.id,CASE WHEN t1.desk = LAG (t1.desk) OVER (ORDER BY t1.desk) THEN NULL ELSE t1.desk END
AS desk,CASE
WHEN t2.segment = LAG (t2.segment) OVER (ORDER BY t2.segment) THEN NULL
ELSE t2.segment
END
AS segment,CASE
WHEN t3.supervisor = LAG (t3.supervisor) OVER (ORDER BY t3.supervisor) THEN NULL
ELSE t3.supervisor
END
AS supervisor
FROM table1 t1,table2 t2,table3 t3
WHERE t1.id = t2.id AND t1.id = t3.id)
WHERE desk IS NOT NULL OR segment IS NOT NULL OR supervisor IS NOT NULL;
结果
ID DESK SEGMENT SUPERVISOR
_______ _____________ __________ _____________
4782 AUTOMOTIVE GLOBAL DANIEL
4782 OIL & GAS JAMES