问题
I have two tables table1 and table2
CREATE TABLE TABLE1 (
EMPLID VARCHAR2(11) NOT NULL,
COMPANY VARCHAR2(3) NOT NULL,
EMPL_RCD SMALLINT NOT NULL,
BALANCE_ID VARCHAR2(2) NOT NULL,
BALANCE_YEAR SMALLINT NOT NULL,
BALANCE_QTR SMALLINT NOT NULL,
BALANCE_PERIOD SMALLINT NOT NULL,
SPCL_BALANCE VARCHAR2(1) NOT NULL,
ERNCD VARCHAR2(3) NOT NULL,
HRS_QTD DECIMAL(13, 2) NOT NULL,
GRS_QTD DECIMAL(13, 2) NOT NULL,
HRS_YTD DECIMAL(13, 2) NOT NULL,
GRS_YTD DECIMAL(13, 2) NOT NULL,
HRS_MTD DECIMAL(13, 2) NOT NULL,
GRS_MTD DECIMAL(13, 2) NOT NULL);
CREATE TABLE TABLE2(EMPLID VARCHAR2(11) NOT NULL,
COMPANY VARCHAR2(3) NOT NULL,
BALANCE_ID VARCHAR2(2) NOT NULL,
BALANCE_YEAR SMALLINT NOT NULL,
BALANCE_QTR SMALLINT NOT NULL,
BALANCE_PERIOD SMALLINT NOT NULL,
EMPL_RCD SMALLINT NOT NULL,
SPCL_BALANCE VARCHAR2(1) NOT NULL,
ERNCD VARCHAR2(3) NOT NULL,
HRS_YTD DECIMAL(13, 2) NOT NULL,
HRS_QTD DECIMAL(13, 2) NOT NULL,
HRS_MTD DECIMAL(13, 2) NOT NULL,
GRS_YTD DECIMAL(13, 2) NOT NULL,
GRS_QTD DECIMAL(13, 2) NOT NULL,
GRS_MTD DECIMAL(13, 2) NOT NULL);
I would like to write a query to fetch data from table1 and table2 returning all the rows from table1 and "matching" value from table2 The matching values imply, when EMPLID,ERNCD matches it should display the rows. All the fields between EMPLID & SPCL_BALANCE are keys.
Sample data for table1:
INSERT INTO table1 VALUES('XX','C','0','CY','2015','2','4','Y','XYZ','0','0','0','0','100001','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','2','5','Y','XYZ','0','0','0','0','100002','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','2','6','Y','XYZ','0','0','0','0','100003','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','3','7','Y','XYZ','0','0','0','0','100004','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','3','9','Y','XYZ','0','0','0','0','100005','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','4','10','Y','XYZ','0','0','0','0','100006','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2015','4','12','Y','XYZ','0','0','0','0','100001','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','1','1','Y','XYZ','0','0','0','0','100002','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','1','2','Y','XYZ','0','0','0','0','100003','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','1','3','Y','XYZ','0','0','0','0','100004','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','2','4','Y','XYZ','0','0','0','0','100005','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','2','6','Y','XYZ','0','0','0','0','100006','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','2','6','Y','DCP','0','100001','0','100001','0','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','2','6','Y','SAV','0','100002','0','100002','0','0');
INSERT INTO table1 VALUES('XX','C','0','CY','2016','2','6','Y','SUP','0','100003','0','100003','0','96949.98');
INSERT INTO table1 VALUES('XX','C','0','FY','2016','4','11','Y','PER','0','100004','0','100004','0','0');
INSERT INTO table1 VALUES('XX','C','0','FY','2016','4','11','Y','RET','0','100005','0','100005','0','0');
INSERT INTO table1 VALUES('XX','C','0','FY','2016','4','11','Y','SUM','0','100006','0','100006','0','0');
Sample data for table 2
INSERT INTO table2 VALUES('XX','C','CY','2015','2','4','0','Y','XYZ','0','0','176','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','2','5','0','Y','XYZ','0','0','176','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','2','6','0','Y','XYZ','0','0','168','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','3','7','0','Y','XYZ','0','0','360','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','3','9','0','Y','XYZ','0','0','168','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','4','10','0','Y','XYZ','0','0','352','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2015','4','12','0','Y','XYZ','0','0','168','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','1','1','0','Y','XYZ','0','0','184','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','1','2','0','Y','XYZ','0','0','168','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','1','3','0','Y','XYZ','0','0','168','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','2','4','0','Y','XYZ','0','0','352','0','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','2','5','0','Y','DCP','0','0','0','100001','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','2','5','0','Y','SAV','0','0','0','100002','0','0')
INSERT INTO table2 VALUES('XX','C','CY','2016','2','5','0','Y','SUP','0','0','0','100003','0','0')
INSERT INTO table2 VALUES('XX','C','FY','2016','4','10','0','Y','PER','0','0','0','100004','0','0')
INSERT INTO table2 VALUES('XX','C','FY','2016','4','10','0','Y','RET','0','0','0','100005','0','0')
I would like to write a query which displays all 18 rows from table1 whenever the EMPLID and ERNCD matches, irrespective of the other keys matches or not.
Output sample
t1.emplid t2.emplid t1.company t2.compnay t1.empl_rcd t2.empl_rcd t1.balance_id t2.balance_id t1.balance_year t2.balance_year t1.balance_qtr t2.balance_qtr t1.balance_period t2.balance_period t1.erncd t2.erncd
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 2 2 4 4 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 2 2 5 5 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 2 2 6 6 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 3 3 7 7 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 3 3 9 9 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 4 4 10 10 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2015 2015 4 4 12 12 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 1 1 1 1 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 1 1 2 2 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 1 1 3 3 ACA ACA
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 2 2 4 4 ACA ACA
10011024 NULL UCS NULL 0 NULL CY NULL 2016 NULL 2 NULL 6 NULL ACA NULL
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 2 2 6 5 DCP DCP
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 2 2 6 5 SAV SAV
10011024 10011024 UCS UCS 0 0 CY CY 2016 2016 2 2 6 5 SUP SUP
10011024 10011024 UCS UCS 0 0 FY FY 2016 2016 4 4 11 10 PER PER
10011024 10011024 UCS UCS 0 0 FY FY 2016 2016 4 4 11 10 RET RET
10011024 NULL UCS NULL 0 NULL CY NULL 2016 NULL 4 NULL 11 NULL SUM NULL
I hope this helps. I am currently using the sql below but not getting all the rows:
FROM
(
select EBCS1.EMPLID ,EBCS1.COMPANY ,EBCS1.BALANCE_ID ,EBCS1.BALANCE_YEAR ,EBCS1.BALANCE_QTR ,
EBCS1.BALANCE_PERIOD ,EBCS1.EMPL_RCD ,EBCS1.SPCL_BALANCE ,EBCS1.ERNCD ,EBCS1.HRS_YTD ,EBCS1.HRS_QTD ,EBCS1.HRS_MTD ,
EBCS1.GRS_YTD ,EBCS1.GRS_QTD ,EBCS1.GRS_MTD
row_number() over (partition by EBCS1.EMPLID order by case when EBCS1.EMPLID is not null then 0 else 1 end asc, EBCS1.ERNCD) rn
from table1 EBCS1 left join
(select distinct EMPLID,EMPL_RCD, COMPANY, BALANCE_ID,BALANCE_YEAR,BALANCE_QTR,BALANCE_PERIOD,ERNCD,SPCL_BALANCE from table2) EBPS1 on
EBCS1.EMPLID=EBPS1.EMPLID AND EBCS1.BALANCE_ID=EBPS1.BALANCE_ID and EBCS1.COMPANY=EBPS1.COMPANY AND EBCS1.ERNCD=EBPS1.ERNCD and EBCS1.BALANCE_PERIOD = EBPS1.BALANCE_PERIOD
AND EBCS1.BALANCE_QTR = EBPS1.BALANCE_QTR AND EBCS1.EMPL_RCD = EBPS1.EMPL_RCD AND EBCS1.BALANCE_YEAR = EBPS1.BALANCE_YEAR
AND EBCS1.SPCL_BALANCE =EBPS1.SPCL_BALANCE ) EBCS
LEFT OUTER JOIN
(
select EBPS1.EMPLID ,EBPS1.COMPANY ,EBPS1.BALANCE_ID ,EBPS1.BALANCE_YEAR ,EBPS1.BALANCE_QTR ,
EBPS1.BALANCE_PERIOD ,EBPS1.EMPL_RCD ,EBPS1.SPCL_BALANCE ,EBPS1.ERNCD ,EBPS1.HRS_YTD ,EBPS1.HRS_QTD ,EBPS1.HRS_MTD ,
EBPS1.GRS_YTD ,EBPS1.GRS_QTD ,EBPS1.GRS_MTD,
row_number() over (partition by EBPS1.EMPLID order by case when EBPS1.EMPLID is not null then 0 else 1 end asc, EBPS1.ERNCD) rn
from table2 EBPS1 left join (select distinct EMPLID,EMPL_RCD,COMPANY,BALANCE_ID,BALANCE_YEAR,BALANCE_PERIOD,ERNCD,SPCL_BALANCE,BALANCE_QTR
from table1) EBCS1 ON
EBCS1.EMPLID=EBPS1.EMPLID AND EBCS1.BALANCE_ID=EBPS1.BALANCE_ID and EBCS1.COMPANY=EBPS1.COMPANY AND EBCS1.ERNCD=EBPS1.ERNCD and EBCS1.BALANCE_PERIOD = EBPS1.BALANCE_PERIOD
AND EBCS1.BALANCE_QTR = EBPS1.BALANCE_QTR AND EBCS1.EMPL_RCD = EBPS1.EMPL_RCD AND EBCS1.BALANCE_YEAR = EBPS1.BALANCE_YEAR AND EBCS1.SPCL_BALANCE =EBPS1.SPCL_BALANCE ) EBPS
ON ( EBPS.EMPLID=EBCS.EMPLID AND EBPS.COMPANY=EBCS.COMPANY AND EBCS.rn=EBPS.rn )
Output using query below:
XX1 CY CY 2 2 1 1 ACA ACA
XX1 CY CY 3 3 1 1 ACA ACA
XX1 CY CY 4 4 2 2 ACA ACA
XX1 CY 6 0 2 0 ACA
XX1 CY 6 0 2 0 DCP
XX1 CY 6 0 2 0 SAV
XX1 CY 6 0 2 0 SUP
XX1 FY 11 0 4 0 SAF
Expected Output:
XX1 CY CY 2 2 1 1 ACA ACA
XX1 CY CY 3 3 1 1 ACA ACA
XX1 CY CY 4 4 2 2 ACA ACA
XX1 CY NULL 6 0 2 0 ACA NULL
XX1 CY CY 6 2 2 5 DCP DCP
XX1 CY CY 6 2 2 5 SAV SAV
XX1 CY CY 6 2 2 5 SUP SUP
XX1 FY FY 11 4 10 10 SAF SAF
回答1:
The only idea that comes to my mind is something like:
select t1.emplid,t1.balance_id,t2.balance_id,t1.balance_period,t2.balance_period,t1.balance_qtr,t2.balance_qtr, t1.erncd,t2.erncd
from table1 t1 join table2 t2
on t1.emplid=t2.emplid
and t1.company=t2.company
and t1.empl_rcd=t2.empl_rcd
and t1.balance_id=t2.balance_id
and t1.balance_year=t2.balance_year
and t1.balance_qtr=t2.balance_qtr
and t1.balance_period=t2.balance_period
and t1.spcl_balance=t2.spcl_balance
and t1.erncd=t2.erncd
union all
select t1.emplid,
t1.balance_id, null balance_id,
t1.balance_period, null balance_period,
t1.balance_qtr, null balance_qtr,
t1.erncd, null erncd
from table1 t1
left join (select * from table2 t3
where not exists
( select 1 from table1 t4
where t3.emplid=t4.emplid
and t3.company=t4.company
and t3.empl_rcd=t4.empl_rcd
and t3.balance_id=t4.balance_id
and t3.balance_year=t4.balance_year
and t3.balance_qtr=t4.balance_qtr
and t3.balance_period=t4.balance_period
and t3.spcl_balance=t4.spcl_balance
)
) t3
on t1.emplid=t3.emplid
and t1.erncd=t3.erncd
where not exists
( select 1 from table2 t2
where t1.emplid=t2.emplid
and t1.company=t2.company
and t1.empl_rcd=t2.empl_rcd
and t1.balance_id=t2.balance_id
and t1.balance_year=t2.balance_year
and t1.balance_qtr=t2.balance_qtr
and t1.balance_period=t2.balance_period
and t1.spcl_balance=t2.spcl_balance
);
In the first part of the query I'm returning all the completely matching rows. In the second one I'm returning all the rows of table1 joined with table2 with the same emplid and erncd (but only on the not matching records).
If that's not responding to your requisites, could you please add the table2 rows in your example and the full expected result?
It's not clear to me if with your data the second union would return duplicates or not.
来源:https://stackoverflow.com/questions/40852905/sql-join-with-when-data-matches