#sql #postgresql #unique #where-clause #having
#sql #postgresql #уникальный #where-предложение #имеющий
Вопрос:
Я пытаюсь найти fact_order_id, в которых есть элементы только для напитков. Это привело бы к тому, что fact_order_id не включал бы никаких продуктов питания.
fact_order_id
fact_order_line_id
category Group
category Name
Я использовал 2 отдельных SQL-запроса ниже. Когда я возвращаюсь и проверяю свою работу, я замечаю, что некоторые fact_order_id в выходных данных не являются заказами только на напитки. Вот 2 отдельных SQL-запроса, которые дают мне одинаковый результат:
select fact_order_id
from my_table
group by fact_order_id
having avg((category_group like 'Beverage%')::int) = 1;
select fact_order_id
from my_table
group by fact_order_id
having avg(CASE WHEN category_group like 'Beverage%' THEN 1 ELSE 0 END)=1;
Оба приведенных выше вывода дают мне одинаковое количество строк. Всякий раз, когда я перепроверяю fact_order_id, некоторые из них будут включать вывод с продуктами питания.
Этот fact_order_id не должен включаться в мои выходные данные, поскольку в заказе есть другие товары, не относящиеся к напиткам. Есть 2 группы категорий, у которых есть название напитка (Напиток (безалкогольный) и напиток (фирменный)). Есть ли лучший способ создания SQL-запроса, чтобы выводить только fact_order_id, которые являются заказами только на напитки?
Я использую версию PostgreSQL: 08.00.0002
Комментарии:
1. Можете ли вы воспроизвести проблему в скрипте: dbfiddle.uk/?rdbms=postgres_9.5
Ответ №1:
Исходя из того, сколько лет вашему PostgreSQL, не могли бы вы, пожалуйста, попробовать это?
select fact_order_id
from my_table
group by fact_order_id
having bool_and((category_group like 'Beverage%'));
Основываясь на вашем комментарии, не могли бы вы, пожалуйста, попробовать этот запрос и поделиться своими результатами?
select fact_order_id, category_group, category_name,
(category_group like 'Beverage%') as is_beverage
from my_table
where fact_order_id = '1 292 757'
Вы можете присоединиться обратно к своей таблице в своих проверках, чтобы увидеть, есть ли проблема. Следующий запрос бессмыслен с точки зрения SQL, но он автоматизировал бы вашу перекрестную проверку:
with bev_orders as (
select fact_order_id
from my_table
group by fact_order_id
having bool_and((category_group like 'Beverage%'))
)
select *
from my_table t
join bev_orders b
on b.fact_order_id = t.fact_order_id
where t.category_group not like 'Beverage%' ;
Комментарии:
1. Я по-прежнему получаю тот же точный результат подсчета строк, что и запросы, которые я перечислил выше. Я приму этот ответ, поскольку в этом запросе используется другая функция (bool_and), чем все, что я пробовал раньше.
2. @Natasha Я не понимаю, как это приведет к возврату вашего примера
fact_order_id
. Вам нет необходимости принимать этот ответ, если он у вас не работает. Я обновил свой ответ запросом, который может помочь нам выяснить, что происходит не так.3. Значение true / false работает для каждой группы категорий. Я бы не хотел, чтобы это
fact_order_id
возвращалось в основной SQL-запрос, поскольку вfact_order_id
нем есть по крайней мере одно false. При перекрестной проверке я не нашелfact_order_id
(пока) в выходных данных, которые включали бы продукт питания.4. @Natasha Я добавил контрольный запрос к своему ответу.
5. Означает ли вывод «Нет строк для отображения», что исходный запрос правильный?
Ответ №2:
Как насчет исключения fact_order_ids, которые, как вы знаете, не подходят?
select distinct fact_order_id
from my_table
where fact_order_id not in (
select distinct fact_order_id
from my_table
where not category_group like 'Beverage%'
);
Комментарии:
1. У меня есть тысячи строк для моего вывода, поэтому исключение fact_order_id не сработало бы, если бы я не проверил каждый fact_order_id отдельно.
2. Вы меня неправильно поняли. Я предлагаю запрос, который работает путем нахождения обратного тому, что вы ищете, fact_order_ids, в котором есть элемент, не относящийся к напиткам, а затем возвращает все fact_order_ids, которых нет в этом первом наборе.
3. Я получаю тот же точный результат подсчета строк, что и запросы, которые я перечислил выше. Я нахожусь в процессе перекрестной проверки my_table на предмет выходных идентификаторов fact_order_ids, которые вы показали.