如何根据条件加入oracle

How to joins in oracle based on condition

我有两个表格如下:

Table苹果:

+----------+----------+---------+
| APPLE_ID | PHONE_ID | IPAD_ID |
+----------+----------+---------+
|        1 |     1001 |    2001 |
|        2 |     1002 |    2002 |
|        3 |     1003 |    2003 |
|        4 |     1004 |    2004 |
+----------+----------+---------+

Table 基伊:

+---------+----------+--------+-----------+
| KEEY_ID |   NAME   | DTL_ID | DEVICE_ID |
+---------+----------+--------+-----------+
|       1 | PHONE_ID |   1001 |       111 |
|       2 | PHONE_ID |   2001 |       111 |
|       3 | IPAD_ID  |   2001 |       222 |
|       4 | PHONE_ID |   1003 |       444 |
|       5 | MAC_ID   |    367 |       333 |
+---------+----------+--------+-----------+

期望的输出:

+----------+----------+---------+-----------------+----------------+
| APPLE_ID | PHONE_ID | IPAD_ID | PHONE_DEVICE_ID | IPAD_DEVICE_ID |
+----------+----------+---------+-----------------+----------------+
|        1 |     1001 |    2001 |             111 | 222            |
|        3 |     1003 |    2003 |             444 | null           |
+----------+----------+---------+-----------------+----------------+

到目前为止尝试过的代码:

SELECT 
APPLE.APPLE_ID,
APPLE.PHONE_ID,
APPLE.IPAD_ID,
NULL AS IPHONE_DEVICE_ID,
KY.DEVICE_ID AS IPAD_DEVICE_ID
FROM APPLE
LEFT JOIN KEEY KY ON APPLE.IPAD_ID=KY.DTL_ID WHERE KY.NAME='IPAD_ID'
UNION
SELECT 
APPLE.APPLE_ID,
APPLE.PHONE_ID,
APPLE.IPAD_ID,
KY.DEVICE_ID AS PHONE_DEVICE_ID,
NULL AS IPAD_DEVICE_ID
FROM APPLE
LEFT JOIN KEEY KY ON APPLE.PHONE_ID=KY.DTL_ID WHERE KY.NAME='PHONE_ID'

这是给了我:

+----------+----------+---------+------------------+----------------+
| APPLE_ID | PHONE_ID | IPAD_ID | IPHONE_DEVICE_ID | IPAD_DEVICE_ID |
+----------+----------+---------+------------------+----------------+
|        1 |     1001 |    2001 | 111              | (null)         |
|        1 |     1001 |    2001 | (null)           | 222            |
|        3 |     1003 |    2003 | 444              | (null)         |
+----------+----------+---------+------------------+----------------+

我想我需要使用 pivot 而不是 Union 来获得同一行的两个 id。

你遇到过这样的场景吗?任何继续进行的指示都会非常有帮助。

提前致谢!

用于上述问题的DDL:

CREATE TABLE APPLE 
( APPLE_ID INTEGER,
 PHONE_ID INTEGER,
 IPAD_ID INTEGER);
 
 INSERT INTO APPLE VALUES (1,1001,2001);
 INSERT INTO APPLE VALUES (2,1002,2002);
 INSERT INTO APPLE VALUES (3,1003,2003);
 INSERT INTO APPLE VALUES (4,1004,2004);
 
 CREATE TABLE KEEY 
( KEEY_ID INTEGER,
 NAME VARCHAR2(50),
 DTL_ID INTEGER,
 DEVICE_ID INTEGER);
 
 INSERT INTO KEEY VALUES (1,'PHONE_ID',1001,111);
 INSERT INTO KEEY VALUES (2,'PHONE_ID',2001,111);
 INSERT INTO KEEY VALUES (3,'IPAD_ID',2001,222);
 INSERT INTO KEEY VALUES (4,'PHONE_ID',1003,444);
 INSERT INTO KEEY VALUES (5,'MAC_ID',367,333);

我想你只需要两个连接:

select a.*, k1.device_id as phone_id, d2.device_id as ipad_id
from apple a join
     keey k1
     on a.phone_id = k1.dtl_id and k1.name = 'PHONE_ID' left join
     keey k2
     on a.ipad_id = k2.dtl_id and k2.name = 'IPAD_ID';

Here 是一个 db<>fiddle(它使用 Postgres 只是因为在 fiddle 中更容易设置,但结果应该是相同的)。

另一种实现相同目的的简单方法是联合:

Select apple_id, phone_id, ipad_id, SUM(PHONE_DEVICE_ID), SUM(IPAD_DEVICE_ID)
from
(Select a.apple_id, a.phone_id, a.ipad_id , 
CASE WHEN k.NAME = 'PHONE_ID' THEN k.DEVICE_ID END PHONE_DEVICE_ID, 0 as IPAD_DEVICE_ID
from apple a
JOIN keey k ON a.phone_id = k.dtl_id AND k.name = 'PHONE_ID'
UNION ALL
Select b.apple_id, b.phone_id, b.ipad_id , 
0 as PHONE_DEVICE_ID, CASE WHEN j.NAME = 'IPAD_ID' THEN j.DEVICE_ID END IPAD_DEVICE_ID
from apple b
JOIN keey j ON b.IPAD_id = j.dtl_id  AND j.name = 'IPAD_ID'
) group by apple_id, phone_id, ipad_id;

O/P:

+----------+----------+---------+-----------------+----------------+
| APPLE_ID | PHONE_ID | IPAD_ID | PHONE_DEVICE_ID | IPAD_DEVICE_ID |
+----------+----------+---------+-----------------+----------------+
| 1        | 1001     | 2001    | 111             | 222            |
+----------+----------+---------+-----------------+----------------+
| 3        | 1003     | 2003    | 444             | 0              |
+----------+----------+---------+-----------------+----------------+