Есть ли способ отрицать предложение WHERE в SQL? - PullRequest
4 голосов
/ 13 февраля 2012

Это мой базовый запрос

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

но мне нужно показать и для других 2 мест

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, или некоторые"аккуратная" альтернатива делать то, что я хочу.

Спасибо !!

PS Я использую 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 ]

6 голосов
/ 13 февраля 2012

Я думаю, что это должно сделать это:

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);
3 голосов
/ 13 февраля 2012

Если я правильно читаю ваш вопрос, вам нужен оператор 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) оценивается как нулевое, что будет рассматриваться как ложное. Если вам нужно сделать этот ноль безопасным, чтобы исключить только строку с обоими этими значениями, вам нужно сделать что-то вроде этого:

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;
0 голосов
/ 13 февраля 2012

Я думаю, что самый простой способ сделать то, что вы хотите, это сгруппировать, а не использовать разные:

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
0 голосов
/ 13 февраля 2012

пожалуйста, попробуйте следующее:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...