SQL Join with when data matches

依然范特西╮ 提交于 2020-01-07 05:34:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!