有没有办法在SQL中否定WHERE子句?

时间:2012-02-13 13:21:11

标签: sql oracle oracle11g oracle-sqldeveloper

这是我的基本查询

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) 
     from table1 b      
     where a.projects = b.projects 
     group by projects)
else 0 end as "WIP days outstanding"
from table1 a

并产生以下输出

Projects                        WIP days outstanding
History - AURANGABAD - NASIK    0
History - PUNE - MUMBAI         0
History - NASIK - MUMBAI        89.92
History - SASAGRAM - MUMBAI     0
History - SASAGRAM - MUMBAI     1386.52
History - AURANGABAD - MUMBAI   83.25

现在我需要显示除第4行以外的所有行。我之所以使用case语句的原因是因为如果我这样做(billing_fy!= 0子句是为了防止由除以0引起的错误)

select projects,
round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) as "WIP days outstanding"
from table1
where billing_fy!=0
group by projects;

我会得到

Projects                        WIP days outstanding
History - SASAGRAM - MUMBAI     1386.52
History - NASIK - MUMBAI        89.92
History - AURANGABAD - MUMBAI   83.25

但我需要为其他两个地方展示

History - AURANGABAD - NASIK    0
History - PUNE - MUMBAI         0

此查询仅显示我不想要的行。

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table1 b     where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where (projects='History - SASAGRAM - MUMBAI' AND billing_fy=0);

并按预期输出

Projects                        WIP days outstanding
History - SASAGRAM - MUMBAI     0

现在问我的问题。 SQL中有没有办法否定WHERE子句?就像在C ++中一样,我只需要在子句前使用not运算符来否定它。因为基本上,我想显示除上面一行之外的所有行。

现在,我已经解决了使用以下代码显示除了我不想要的行之外的所有行的问题

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table1 b   where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where projects not in ('History - SASAGRAM - MUMBAI') and billing_fy!=0
union all
select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table1 b   where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where projects not in ('History - SASAGRAM - MUMBAI') and billing_fy=0
union all
select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table1 b    where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where projects='History - SASAGRAM - MUMBAI' and billing_fy!=0;

这会产生所需的输出

Projects                         WIP days outstanding
History - NASIK - MUMBAI         89.92
History - AURANGABAD - MUMBAI    83.25
History - AURANGABAD - NASIK     0
History - PUNE - MUMBAI          0
History - SASAGRAM - MUMBAI      1386.52

这只是一种破旧的方式,我想知道是否可以否定WHERE子句,或者做一些“整洁”的替代方法来做我想做的事。

谢谢!

P.S。我使用 SQL Developer Oracle 11g (以防万一有人问)

编辑按要求输入值

Projects                      Cost_Project  Billing_FY
History - NASIK - MUMBAI      65696067.99   54937478.46
History - NASIK - MUMBAI      41385613.61   151909546.44
History - NASIK - MUMBAI      18029488.91   216353866.92
History - AURANGABAD - MUMBAI 33191393.23   57073935.95
History - AURANGABAD - MUMBAI 52681451.68   139055661.74
History - AURANGABAD - MUMBAI 74576522.31   390092578.24
History - PUNE - MUMBAI       0             0
History - PUNE - MUMBAI       0             0
History - PUNE - MUMBAI       0             0
History - SASAGRAM - MUMBAI   107540114.08  40653734.06
History - SASAGRAM - MUMBAI   209167760.1   28823862.66
History - SASAGRAM - MUMBAI   0             0
History - AURANGABAD - NASIK  0             0
History - AURANGABAD - NASIK  0             0
History - AURANGABAD - NASIK  0             0

4 个答案:

答案 0 :(得分:6)

我认为应该这样做:

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table1 b     where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where (projects != 'History - SASAGRAM - MUMBAI' OR billing_fy != 0);

答案 1 :(得分:3)

如果我正确地阅读了您的问题,您需要的是not运算符:

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) 
from table1 b     
where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where not (projects='History - SASAGRAM - MUMBAI' AND billing_fy=0);

正如@ShannonSeverance指出的那样,如果在任一字段中都有空值,这将导致问题,因为not (false and null)计算为null,这将被视为false。如果你需要使这个null安全,以便它只排除具有这两个值的行,你需要做这样的事情:

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) 
from table1 b
where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table1 a
where (not (projects='History - SASAGRAM - MUMBAI' AND billing_fy=0))
      or projects is null 
      or billing_fy is null;

答案 2 :(得分:0)

请尝试以下方法:

select distinct a.projects , case when(billing_fy!=0)
then(select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) from table b     where a.projects = b.projects group by projects)
else 0 end as "WIP days outstanding"
from table a
where (projects!='History - SASAGRAM - MUMBAI' AND billing_fy!=0);

答案 3 :(得分:0)

我认为做你想做的最简单的方法就是分组,而不是使用不同的方法:

select a.projects, 
       case when sum(billing_fy!=0)
            then (select round(((sum(cost_project)/(sum(billing_fy)/((10/12)*365)))),2) 
                  from table1 b
                  where a.projects = b.projects
                  group by projects)
            else 0 end as "WIP days outstanding"
from table1 a
group by a.projects