仅返回符合条件的id的记录

时间:2015-07-06 07:41:23

标签: sql oracle

我需要返回符合以下条件的不同ID记录: 必须有字段reason_of_creation = 1的记录 并且不得包含字段reason_of_creation = 0或null的记录 在同一时间。 虽然我能够做到这一点,但我一直想知道是否有更优雅(甚至推荐)的方式。

以下是我所拥有的匿名版本:

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;

示例数据:

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

期望的结果将是some_id = 2, 5

的记录列表

2 个答案:

答案 0 :(得分:2)

在我看来,你的查询过度,你需要的只是一些后期聚合过滤

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 :(得分:1)

我认为存在更优雅的查询,并且它基于假设reasoson_of_crdeation字段是整数,因此最小可能的值,大于0是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)