У меня есть таблица, которая выглядит так:
ACCOUNT hour_count
A 24
B 24
C 23
D 22
Я хочу создать оператор sql, который просто возвращает «1», когда выполняются ВСЕ условия:
when account is A, hour_count = 24
when account is B, hour_count = 24
when account is C, hour_count > 22
when account is D, hour_count > 22
Как я могу этого добиться?
Я попытался использовать оператор CASE, но не смог если не понять, как включить несколько условий. Это не сработает с оператором AND внутри одного оператора WHEN:
SELECT
CASE
WHEN ((ACCOUNT = 'A' AND hour_count = 24) )
THEN 1
END
FROM hour_counts
Что делать, если одна или несколько учетных записей (A, B, C, D) отсутствуют, но имеющиеся удовлетворяют условию?
@Rajat Я думаю, тогда их значение неизвестно (NULL), а NULL является поглощающим элементом в алгебре отношений.
@LajosArpad Извините, я имел в виду, что эти учетные записи отсутствуют в данных, а не имеют нулевые значения.
@Rajat, можете ли вы показать свой полный запрос, включая где? Кроме того, я бы предложил ELSE NULL
в блоке case-when.
@LajosArpad Я не задавал вопрос
@Rajat хорошо, пожалуйста, извини меня
если вы вернули только одну 1, если все условия соблюдены, иначе ничего не вернулось
with cte as (
select case
when account in (‘A’,’B’) and hour_count = 24) then 1
when account in (‘C’,’D’) and hour_count > 22) then 1
end as c_count
from hour_count)
select 1 as one
from cte
having sum(c_count)=4 —- if all conditions met
Вы можете превратить каждую проверку в предикат exists в предложении where:
(Необязательный образец тестовых данных):
create or replace table T1 as
select
COLUMN1::string as "ACCOUNT",
COLUMN2::float as "HOUR_COUNT"
from (values
('A',24),
('B',24),
('C',23),
('D',22)
);
Запрос с существующими предикатами для каждой проверки:
select 1 as CHECKS where
exists (select 1 from T1 where ACCOUNT = 'A' and HOUR_COUNT = 24) and
exists (select 1 from T1 where ACCOUNT = 'B' and HOUR_COUNT = 24) and
exists (select 1 from T1 where ACCOUNT = 'C' and HOUR_COUNT > 22) and
exists (select 1 from T1 where ACCOUNT = 'D' and HOUR_COUNT > 22)
;
Обратите внимание, что с тестовыми данными это не вернет строку. Это связано с тем, что он не проходит проверку для учетной записи D. Вы можете изменить проверку на >= или изменить значение для D, чтобы увидеть результат прохождения существующих проверок.
Если вам просто нужно, чтобы он возвращал 1 или 0, становится проще
select iff(count(distinct account)=4,1,0)
from t
where (account in ('A','B') and hour_count = 24) or
(account in ('C','D') and hour_count > 22)
Это должно работать именно так. В чем была твоя ошибка?