我有三个表 CIS_GROUP,CUSTOMER,CUSTOMER_TEMP 和数据。
我的查询目标如下:
1)当 CUSTOMER 表中存在相同客户时,从 CUSTOMER_TEMP 获取数据。
2)当客户仅存在于 CUSTOMER_TEMP 表中时,从 CUSTOMER_TEMP 获取数据。
2)当客户仅存在于 CUSTOMER 表中时,从 CUSTOMER 获取数据。
表格脚本&插入脚本如下
CREATE TABLE ABABILFE.CIS_GROUP
(ID NUMBER
,GROUP_NAME VARCHAR2(100)
)
/
CREATE TABLE ABABILFE.CUSTOMER
(ID NUMBER
,GROUP_ID NUMBER
,CUST_NAME VARCHAR2(100)
,ADDRESS VARCHAR2(200)
,PHONE VARCHAR2(20)
,EMAIL VARCHAR2(50)
)
/
CREATE TABLE ABABILFE.CUSTOMER_TEMP
(ID NUMBER
,GROUP_ID NUMBER
,CUST_NAME VARCHAR2(100)
,ADDRESS VARCHAR2(200)
,PHONE VARCHAR2(20)
,EMAIL VARCHAR2(50)
)
插入脚本
SET DEFINE OFF;
Insert into CIS_GROUP
(ID,GROUP_NAME)
Values
(1,'Albert');
Insert into CIS_GROUP
(ID,GROUP_NAME)
Values
(2,'Eric');
COMMIT;
-------------------------------------------
SET DEFINE OFF;
Insert into CUSTOMER
(ID,CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(1,'Aston','NewYork','0011','aston@gmail.com');
Insert into CUSTOMER
(ID,GROUP_ID,CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(2,1,'Albert','Canada','0022',NULL);
Insert into CUSTOMER
(ID,GROUP_ID, CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(3,1,'Bob','Canada',NULL,'bob123@gmail.com');
Insert into CUSTOMER
(ID,GROUP_ID,CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(4,1,'Charles','Canada',NULL,'charles@gmail.com');
COMMIT;
-------------------------------------------
SET DEFINE OFF;
Insert into CUSTOMER_TEMP
(ID,GROUP_ID, CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(3, 1,'Bob','Canada','0023','bob@yahoo.com');
Insert into CUSTOMER_TEMP
(ID,GROUP_ID, CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(5,2,'Don','London','123','don@hotmail.com');
Insert into CUSTOMER_TEMP
(ID,GROUP_ID,CUST_NAME,ADDRESS,PHONE,EMAIL)
Values
(6,2,'Eric','London',null,'eric@gmail.com');
COMMIT;
表格数据
CIS_GROUP Table Data
| ID |GROUP_NAME |
| -- | --------- |
| 1 | Albert |
| 2 | Eric |
CUSTOMER Table Data
| ID | GROUP_ID | NAME | ADDRESS | PHONE | EMAIL |
| ---| ---------| ---------| --------- | ----- | ---------------- |
| 1 | | Aston | New York | 0011 |aston@gmail.com |
| 2 | 1 | Albert | Canada | 0022 | |
| 3 | 1 | Bob | Canada | |bob123@gmail.com |
| 4 | 1 | Charles | Canada | |charles@gmail.com |
CUSTOMER_TEMP Table Data
| ID | GROUP_ID | NAME | ADDRESS | PHONE | EMAIL |
| ---| ---------| ---------| --------- | ----- | ---------------- |
| 3 | 1 | Bob | Canada | 0023 | bob@yahoo.com |
| 5 | 2 | Don | London | 123 | don@hotmail.com |
| 6 | 2 | Eric | London | | eric@gmail.com |
我为我想要的结果写了以下查询
SELECT * FROM
(
SELECT CUSTOMER_TEMP.id
,GROUP_ID
,cust_name
,address
,phone
,email
FROM CIS_GROUP,CUSTOMER_TEMP
WHERE CIS_GROUP.ID = CUSTOMER_TEMP.GROUP_ID
AND CIS_GROUP.ID = :PID
)TABLE1
UNION ALL
SELECT * FROM
(
SELECT CUSTOMER.id
,GROUP_ID
,cust_name
,address
,phone
,email
FROM CIS_GROUP,CUSTOMER
WHERE CIS_GROUP.ID = CUSTOMER.GROUP_ID
AND CIS_GROUP.ID = :PID
AND CUSTOMER.ID NOT IN (SELECT CUSTOMER_TEMP.id
FROM ABABILFE.CUSTOMER_TEMP)
)TABLE2
ORDER BY 1
查询结果/所需结果
My Desire Result (When parameter(:PID) value is 1)
| ID | GROUP_ID | NAME | ADDRESS | PHONE | EMAIL |
| ---| ---------| ---------| --------- | ----- | ---------------- |
| 2 | 1 | Albert | Canada | 0022 | |
| 3 | 1 | Bob | Canada | 0023 | bob@yahoo.com |
| 4 | 1 | Charles | Canada | | charles@gmail.com|
My Desire Result (When parameter(:PID) value is 2)
| ID | GROUP_ID | NAME | ADDRESS | PHONE | EMAIL |
| ---| ---------| ---------| --------- | ----- | ---------------- |
| 5 | 2 | Don | London | 123 | don@hotmail.com |
| 6 | 2 | Eric | London | | eric@gmail.com |
如何更有效地编写此查询/优化方式?
答案 0 :(得分:0)
您也可以使用CTE
:
with t as (select id, cust_name, address, phone, email
from customer_temp
where group_id = 1)
select * from t
union all
select id, cust_name, address, phone, email from customer
where group_id = 1
and not exists (select 1 from t where id = customer.id)
或对行进行排名,给出第二个表优先级:
select id, cust_name, address, phone, email
from (
select rank() over (partition by id order by src) rnk, c.*
from (
select 1 src, id, cust_name, address, phone, email
from customer_temp where group_id = 1
union all
select 2 src, id, cust_name, address, phone, email
from customer where group_id = 1) c )
where rnk = 1 order by id
两个查询都产生了期望的结果。您提供的insert
中存在轻微错误。
答案 1 :(得分:0)
可以删除表CIS_GROUP,因为:
而不是"联合所有"用"不在"在第二个查询中,您可以使用完全外部联接,通过客户ID与NVL函数联接以从右表中获取数据。 NVL的第一个参数定义哪个表是主数据源。
最终查询如下所示:
SELECT NVL(CT.id, C.ID) AS ID
,NVL(CT.GROUP_ID, C.GROUP_ID) AS GROUP_ID
,NVL(CT.cust_name, C.CUST_NAME) AS CUST_NAME
,NVL(CT.address, C.ADDRESS) AS ADDRESS
,NVL(CT.phone, C.PHONE) AS PHONE
,NVL(CT.email, C.EMAIL) AS EMAIL
FROM CUSTOMER C
FULL OUTER JOIN CUSTOMER_TEMP CT ON C.ID = CT.ID
WHERE (CT.GROUP_ID = :PID OR C.GROUP_ID = :PID)
此版本有更好的执行计划。你可以在这里试试:SQL Fiddle
*编辑:以前的版本不符合问题的要求。