仅当存在所有必需列且不为NULL时,SQL查询才返回数据

时间:2017-01-03 19:19:01

标签: sql oracle sybase

ID | Type     | total
1    Purchase   12
1    Return     2
1    Exchange   5
2    Purchase   null
2    Return     5
2    Exchange   1
3    Purchase   34
3    Return     4
3    Exchange   2
4    Purchase   12
4    Exchange   2

以上是样本数据。我想要回归的是:

ID | Type     | total
 1    Purchase   12
 1    Return     2
 1    Exchange   5
 3    Purchase   34
 3    Return     4
 3    Exchange   2

因此,如果一个字段总共为空,或者该ID的值不是全部存在,则完全忽略该ID。我怎么能这样做呢?

4 个答案:

答案 0 :(得分:2)

您可以使用exists。我想你打算:

select t.*
from t
where exists (select 1
              from t t2
              where t2.id = t.id and t2.type = 'Purchase' and t2.total is not null
             ) and
      exists (select 1
              from t t2
              where t2.id = t.id and t2.type = 'Exchange' and t2.total is not null
             ) and
      exists (select 1
              from t t2
              where t2.id = t.id and t2.type = 'Return' and t2.total is not null
             );

有很多方法可以简化"这样:

select t.*
from t
where 3 = (select count(distinct t2.type)
           from t t2
           where t2.id = t.id and
                 t2.type in ('Purchase', 'Exchange', 'Return') and
                 t2.total is not null
          );

答案 1 :(得分:2)

我会把它写成一个连接,没有子查询:

SELECT pur.id, pur.total AS Purchase, exc.total AS Exchange, ret.total AS Return
FROM MyTable as pur
INNER JOIN MyTable AS exc ON exc.id=pur.id AND exc.type='Exchange'
INNER JOIN MyTable AS ret ON ret.id=pur.id AND ret.type='Return'
WHERE pur.type='Purchase'

内连接意味着如果找不到给定id的三个具有不同值的行中的任何一个,则结果中不包含任何行。

答案 2 :(得分:1)

分析函数是解决此类问题的好方法。基表只读取一次,并且不需要连接(显式或隐式,如EXISTS条件或相关子查询)。

在下面的解决方案中,我们计算每个id的“购买”,“交易”和“返回”的不同值,同时忽略其他值(假设确实是要求),并单独计算总数{{每个null的{​​{1}}列中的1}}。那么在外部查询中仅选择“所需”行就变得微不足道了。

total

<强>输出

id

答案 3 :(得分:1)

即使将新值添加到type

,这也应该可以正常工作
select * from t where 
ID not in(select ID from t where 
t.total is null or t.[Type] is null)