简体   繁体   中英

Returning only id's of records that meet criteria

I need to return distinct ID's of records which meet following conditions : must have records with field reason_of_creation = 1 and must NOT have records with field reason_of_creation = 0 or null in the same time. While i was able to do it, i keep wondering is there more elegant (even recommended) way of doing it.

Here is anonymized version of what i have :

select distinct st.some_id from (
        select st.some_id, wanted.wanted_count as wanted, unwanted.unwanted_count as unwanted
          from some_table st
          left join (
                select st.some_id, count(st.reason_of_creation) as wanted_count
                  from some_table st
                 where st.reason_of_creation=1
                 group by st.some_id
                 ) wanted on wanted.some_id = st.some_id
          left join (
                select st.some_id, count(st.reason_of_creation) as unwanted_count
                  from some_table st
                 where st.reason_of_creation=0
                 group by st.some_id
                 ) unwanted on unwanted.some_id = st.some_id
where wanted.wanted_count >0 and (unwanted.unwanted_count = 0 or unwanted.unwanted_count is null)
   ) st;

Sample data :

some_id    reason_of_creation
      1           1
      1           0
      2           1
      3           null
      4           0
      4           1
      5           1

desired result would be list of records with some_id = 2, 5

It seems to me your query is overkill,all you need is some post aggregation filtering

SELECT some_id FROM t
GROUP BY some_id
HAVING SUM(CASE WHEN reason_of_creation = 1 THEN 1 ELSE 0 END)>0
AND SUM(CASE WHEN reason_of_creation = 0 OR reason_of_creation IS NULL THEN 1 ELSE 0 END)=0

I think that more elegant query exists and it is based on assumption what reasoson_of_crdeation field is integer, so minimal possible it's value, which greater than 0 is 1

This is for possible negative values for reasoson_of_crdeation:

select someid from st
where reasoson_of_crdeation != -1
group by someid
having(min(nvl(abs(reasoson_of_crdeation), 0)) = 1)

or

select someid from st
group by someid
having(min(nvl(abs(case when reasoson_of_crdeation = -1 then -2 else reasoson_of_crdeation end), 0)) = 1)

And this one in a case if reasoson_of_crdeation is non-negative integer:

select someid from st
group by someid
having(min(nvl(reasoson_of_crdeation, 0)) = 1)

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