如何根据条件加入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 |
+----------+----------+---------+-----------------+----------------+
我有两个表格如下:
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 |
+----------+----------+---------+-----------------+----------------+