2015-07-06 7 views
1

мне нужно вернуть отчетливыми идентификаторы записей, которые удовлетворяют следующие условия: должен иметь записи с полем reason_of_creation = 1 и не должен иметь записи с полем reason_of_creation = 0 или в том же нулевая время. Пока я был в состоянии сделать это, я продолжаю задаваться вопросом, есть ли более элегантный (даже рекомендуемый) способ сделать это.Возвращаясь только идентификаторы записей, которые соответствуют критериям

Вот анонимная версию того, что у меня есть:

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 данные:

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

желаемого результат будет список записей с some_id = 2, 5

ответ

2

Мне кажется, ваш запрос overkill, все, что вам нужно, - это фильтрация пост-агрегации

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 
+1

простой и элегантный – ninesided

+1

Это именно то, что я надеялся получить здесь, более простой способ сделать это, благодаря мужчине! –

1

Я думаю, что более элегантный запрос существует и оно основано на предположении, что reasoson_of_crdeation поле является целым числом, поэтому минимально возможным это значение, которое больше чем-1

Это возможных отрицательных значений для reasoson_of_crdeation:

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

или

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) 

И это один в случае, если reasoson_of_crdeation является неотрицательным целым числом:

select someid from st 
group by someid 
having(min(nvl(reasoson_of_crdeation, 0)) = 1) 
Смежные вопросы