#sql #postgresql
#sql #postgresql
Вопрос:
я хочу найти продукты, у которых нет заказов в определенном месяце
у меня здесь три таблицы products, productorder, orderitems
Products
id | name | price
ProductOrder
id | total_amount | order_date
OrderItems
id| product_id | order_id
это запрос, который я пробовал
select * from products p
left join orderitems oi on oi.product_id = p.id
left join productorder po on oi.order_id= po.id
where extract('month' from po.order_date) = 1
and po.id is null
но это дает результат empyt.. Итак, как я могу найти результаты
Ответ №1:
Это звучит как not exists
:
select p.*
from products p
where not exists (select 1
from productorder po join
orderitems oi
on oi.order_id = po.id
where oi.product_id = p.id and
po.order_date >= '2020-12-01' and
po.order_date < '2021-01-01'
);
Комментарии:
1. извините, я не силен в sql .. я думал, что использование объединений более эффективно, чем подзапрос.. итак, я искал решение, которое использует объединения вместо подзапроса… Позвольте мне спросить вас об одном, почему мы не можем решить это с помощью объединений … если вы не возражаете, не могли бы вы уточнить…
2. @tstudent . . Вы можете решить это с помощью объединений (как показывают другие ответы). В большинстве баз данных
left join
иnot exists
будут иметь аналогичную производительность.in
часто имеет худшую производительность.
Ответ №2:
Вы почти на месте. Просто используйте условие extract('month' from po.order_date) = 1
в LEFT JOIN
следующем:
select *
from products p
left join orderitems oi on oi.product_id = p.id
left join productorder po on oi.order_id= po.id
and extract('month' from po.order_date) = 1
where oi.id is null;
Кроме того, как упоминалось в ответе Гордона, лучше использовать dates
extract
функцию, а не.
— обновить
select *
from products p
left join
(select oi.product_id
from orderitems oi
join productorder po on oi.order_id= po.id
and extract('month' from po.order_date) = 1) oi
On p.id = oi.product_id
where oi.product_id is null;
Комментарии:
1. большое спасибо @popeye за вашу поддержку.. у меня есть один запрос, почему «где извлечь (‘month’ из po.order_date) = 1 и po.id is null » также не работает из вашего ответа po.id не работает и oi.id is null работает . почему так .. если вы не возражаете, не могли бы вы объяснить….
Ответ №3:
Что-то подобное сработало бы:
select * from products p
where p.id NOT IN (
select oi.product_id from orderitems oi
inner join productorder po on oi.order_id= po.id
where date_part('month', po.order_date) = 1
)
Вы можете проверить простой пример в SQLFiddle.
Выше будут получены идентификаторы продуктов, которые не были проданы в первый месяц 2020 года. Это делается с помощью NOT IN()...
и путем выбора всех идентификаторов продуктов, у которых были продажи в этом месяце, в подзапросе.
Комментарии:
1. что эффективно с помощью join или нет в