简体   繁体   中英

How to Choose a specific value from a table and to avoid duplicates?

I have two tables:

MainTable

id AccountNum  status

1  11001   active
2  11002   active
3  11003   active
4  11004   active

AddTable

id  date     description
1  01.2020   ACCOUNT.SET
1  02.2020   ACCOUNT.CHANGE
1  03.2020   ACCOUNT.REMOVE
2  04.2020   ACCOUNT.SET
2  05.2020   ACCOUNT.CHANGE
3  08.2020   ACCOUNT.SET
4  05.2020   ACCOUNT.SET
4  09.2020   ACCOUNT.REMOVE

I need to get a such result:

EffectiveFrom is date when Account was set, EffectiveTo is date when Account was removed

id AccountNum EffectiveFrom  EffectiveTo
1  11001       01.2020         03.2020
2  11002       04.2020          null 
3  11003       08.2020          null
4  11004       05.2020         09.2020

The problem is that after joining on AddTable I get the duplicates, but I need just one row on every Id and only dates where the description in ACCOUNT.SET,ACCOUNT.REMOVE.

Are you looking for left join ?

  select m.id         as id,
         m.AccountNum as AccountNum,
         a.date       as EffectiveFrom,
         b.date       as EffectiveTo
    from MainTable m left join
         AddTable a on (a.id = m.id and a.description = 'ACCOUNT.SET') left join
         AddTable b on (b.id = m.id and b.description = 'ACCOUNT.REMOVE') 
order by m.AccountNum

Use a PIVOT and a LEFT OUTER JOIN :

SELECT m.id,
       a.EffectiveFrom,
       a.EffectiveTo
FROM   MainTable m
       LEFT OUTER JOIN
       (
         SELECT *
         FROM   AddTable
         PIVOT( MAX( dt ) FOR description IN (
           'ACCOUNT.SET' AS EffectiveFrom,
           'ACCOUNT.REMOVE' AS EffectiveTo
         ) )
       ) a
       ON ( a.id = m.id )
ORDER BY m.id

So for your test data:

CREATE TABLE MainTable ( id, AccountNum, status ) AS
SELECT 1, 11001, 'active' FROM DUAL UNION ALL
SELECT 2, 11002, 'active' FROM DUAL UNION ALL
SELECT 3, 11003, 'active' FROM DUAL UNION ALL
SELECT 4, 11004, 'active' FROM DUAL;

CREATE TABLE AddTable ( id, dt, description ) AS
SELECT 1, DATE '2020-01-01', 'ACCOUNT.SET' FROM DUAL UNION ALL
SELECT 1, DATE '2020-01-02', 'ACCOUNT.CHANGE' FROM DUAL UNION ALL
SELECT 1, DATE '2020-01-03', 'ACCOUNT.REMOVE' FROM DUAL UNION ALL
SELECT 2, DATE '2020-01-04', 'ACCOUNT.SET' FROM DUAL UNION ALL
SELECT 2, DATE '2020-01-05', 'ACCOUNT.CHANGE' FROM DUAL UNION ALL
SELECT 3, DATE '2020-01-08', 'ACCOUNT.SET' FROM DUAL UNION ALL
SELECT 4, DATE '2020-01-05', 'ACCOUNT.SET' FROM DUAL UNION ALL
SELECT 4, DATE '2020-01-09', 'ACCOUNT.REMOVE' FROM DUAL;

This outputs:

\nID | EFFECTIVEFROM | EFFECTIVETO\n-: |  :------------ |  :---------- \n 1 |  01-JAN-20 |  03-JAN-20   \n 2 |  04-JAN-20 |  null       \n 3 |  08-JAN-20 |  null       \n 4 |  05-JAN-20 |  09-JAN-20   \n

db<>fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM