简体   繁体   中英

SQL case with partition by and select rows with specific value

I have a scenario in which I have to use a case condition in which if the value matches then I need to get value from a table otherwise I need to hard code it to 1 and 0 .

Table License :

Number   permit   reviewpermit   State
---------------------------------------
101       0        1              TX
101       1        0              OK
101       1        1              NC
102       1        1              LA
102       0        1              OK

Condition :

  1. If any state is 'TX' for a 'Number' group, then select 'permit', 'reviewpermit' values from the TX state for all other states for that 'Number' group.
  2. If it's some other state for a 'Number' group then select '1' as 'permit' and '0' as 'reviewpermit' for all states for that 'Number' group.

Desired output:

Number   permit   reviewpermit   State
--------------------------------------
101       0        1              TX
101       0        1              OK
101       0        1              NC
102       1        0              LA     
102       1        0              OK

The 101 group has all permit and reviewpermit values according to Texas state The 102 group has all permit and reviewpermit values '1' and '0' respectively.

This is the code I have written so far:

 SELECT
     Number,
     MAX(CASE WHEN State = 'TX' THEN Permit ELSE 1 END) OVER (PARTITION BY [Number]) AS permit, 
     MAX(CASE WHEN State = 'TX' THEN ReviewPermit ELSE 0 END) OVER (PARTITION BY [Number]) AS reviewpermit, 
     state
 FROM 
     License

But it doesn't return the desired output.

I think this logic does what you want:

select Number,
       coalesce(MAX(CASE WHEN State = 'TX'  THEN Permit END) OVER (PARTITION BY [Number]),
                1) as permit, 
       coalesce(MAX(CASE WHEN State = 'TX' THEN ReviewPermit END) OVER (PARTITION BY [Number]),
                0) AS reviewpermit, state
from License;

This checks for "Texas" in the MAX() . If it is not there, the value is NULL , so the COALESCE() picks up the default value.

With a left self join:

select l1.[Number],
  case when l2.[State] = 'TX' then l2.permit else 1 end permit,
  case when l2.[State] = 'TX' then l2.reviewpermit else 0 end reviewpermit,
  l1.[State]
from License l1 left join License l2
on l2.[Number] = l1.[Number] and l2.[State] = 'TX' 

See the demo .
Results:

> Number | permit | reviewpermit | State
> -----: | -----: | -----------: | :----
>    101 |      0 |            1 | TX   
>    101 |      0 |            1 | OK   
>    101 |      0 |            1 | NC   
>    102 |      1 |            0 | LA   
>    102 |      1 |            0 | OK 

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