简体   繁体   中英

SQL Left join same table but with condition possible?

I have a main Table

|-------------|------------|
| Procedure   | Modifier   |
|:------------|:-----------|
|     AA      |     00     |
|     AA      |     21     |
|     AA      |     26     |
|-------------|------------|

and a rates Table

|-------------|------------|-------|
| Procedure   | Modifier   | Rate  |
|:------------|:-----------|-------|
|     AA      |     00     | $10   |
|     AA      |     21     | $20   |
|     AA      |     QA     | $30   |
|-------------|------------|-------|

I am looking to left join the rate table to main table ON procedure AND modifier, to find the rate.

However, if there is no matching procedure AND modifier, then I want to join by procedure and modifier 00 to get the rate of $10.

End result to look like this, |

-------------|------------|------|
| Procedure   | Modifier   | Rate |
|:------------|:-----------|------|
|     AA      |     00     |$10   |
|     AA      |     21     |$20   |
|     AA      |     26     |$10   |
|-------------|------------|------|

NOT

|-------------|------------|------|
| Procedure   | Modifier   | Rate |
|:------------|:-----------|------|
|     AA      |     00     |$10   |
|     AA      |     21     |$20   |
|     AA      |     26     |null  |
|-------------|------------|------|

I suppose 'worse' case is to do this separately and split into two statements. Where my first left join would be by proc and modifier then later in my second statement just by procedure? Is there a way to do this within one statement?

You can do this nice and simple with two left-joins.

Note that this is very similar to Kazi's answer, just with a much more straightforward syntax

select
    m.[Procedure],
    m.Modifier,
    isnull(r.rate, r2.rate) rate
from maintable m
left join rates r on m.[Procedure] = r.[Procedure] and m.Modifier = r.Modifier  
left join rates r2 on m.[Procedure] = r2.[Procedure]
    and r2.Modifier = '00'
    and r.rate is null

Schema and insert statements:

 create table maintable ([Procedure]   varchar(10), Modifier   varchar(10));
 insert into maintable values(     'AA'  ,        '00');     
 insert into maintable values(     'AA' ,         '21');
 insert into maintable values(     'AA',          '26'); 
 
 create table  rates ( [Procedure]   varchar(10), Modifier   varchar(10), Rate  varchar(10));
 insert into rates values(     'AA'        ,   '00',      '$10');
 insert into rates values(     'AA'       ,    '21' ,     '$20');
 insert into rates values(     'AA'      ,     'QA'  ,    '$30');

Query#1 (with subquery):

     select m.[Procedure]   , m.Modifier ,(case when r.rate is null then (select rate from rates where rates.[procedure]=m.[procedure] and rates.modifier='00') else r.rate  end)rate
     from maintable m
     left join rates r on m.[Procedure]  =r.[Procedure]   and    m.Modifier  =r.Modifier  
     

Output:

Procedure Modifier rate
AA 00 $10
AA 21 $20
AA 26 $10

Query#2 (with outer apply):

     select m.[Procedure]   , m.Modifier ,(case when r.rate is null then t.rate else r.rate  end)rate
     from maintable m
     left join rates r on m.[Procedure]  =r.[Procedure]   and    m.Modifier  =r.Modifier  
     outer apply(select rate from rates where rates.[Procedure]=m.[Procedure] and rates.modifier='00')t

Output:

Procedure Modifier rate
AA 00 $10
AA 21 $20
AA 26 $10

db<>fiddle here

You can use a CASE statement. The example below does a left join from the rate table on the main table matching procedure and modifier. The case statement replaces null values with 10 or uses the rate if it exists.

select 
    m.procedure,
    m.modifier,
    case when r.rate is null then 10 else r.rate end as rate
from main_table m
left join rates_table r on (m.procedure = r.procedure and m.modifier = r.modifier)

A variant on this is to use an apply operator instead of a correlated subquery in the select clause, and instead of a case expression it is also possible to use coalesce, and here 10 can be used if there is no matching rate from either the left join or the outer apply:

select 
     m.[procedure]
   , m.modifier
   , coalesce(r.rate, oa.rate, 10) as rate
from maintable m
left join rates r on m.[procedure] = r.[procedure] and m.modifier = r.modifier
outer apply (
    select rate 
    from rates 
    where rates.[procedure]=m.[procedure] and rates.modifier='00'
    ) oa

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