Я работаю над системой заказа на основе базы данных PostgreSQL, поэтому у меня есть таблица OrderLines
следующего вида:
order_id int
product_id int
quantity int
Затем каждый заказ состоит из одной строки в этой таблице для каждого уникального заказанного продукта.
Я пытаюсь выполнить запросы вида:
Условие здесь потенциально может иметь глубоко вложенные предложения. Заказов могут быть миллионы, а в заказе более 10 тыс. Строк. Условия не могут быть известны заранее. Если товара нет в заказе, его количество необходимо вернуть как 0.
Есть ли у вас какие-либо указания относительно написания запросов с условиями, охватывающими несколько строк, например этой?
Готово. PostgreSQL.
Вы можете использовать условное агрегирование. Например, для первого:
For each order containing products A, B and C, give me the quantities for products C and D
select order_id,
sum(quantity) filter (where product_id = C) as c_quantity,
sum(quantity) filter (where product_id = D) as d_quantity
from orderlines ol
group by order_id
having count(*) filter (where product_id = A) > 0 and
count(*) filter (where product_id = B) > 0 and
count(*) filter (where product_id = C) > 0 ;
Остальные вопросы можно решить с помощью аналогичной логики, изменив условия having
или sum()
s.
Я бы подумал, если бы вы суммировали количества каждой детали для всех заказов в CTE, например:
with summary as (
select
order_id,
sum (case when product_id = 'A' then quantity else 0 end) as a,
sum (case when product_id = 'B' then quantity else 0 end) as b,
sum (case when product_id = 'C' then quantity else 0 end) as c,
sum (case when product_id = 'D' then quantity else 0 end) as d
from table
where quantity != 0
group by order_id
)
(Боковое примечание - вы сказали, что product_id является целым числом, но перечислили значения, которые являются текстом - я предполагаю, что есть разумное объяснение, но я не пытался согласовать это)
Вы можете использовать это как основу для ответа на каждый из трех вопросов:
Для каждого заказа, содержащего продукты A, B и C, укажите количество продуктов C и D.
select order_id, c, d
from summary
where a > 0 and b > 0 and c > 0
Для каждого заказа, содержащего продукты A и (B или C), дайте мне количество продукта D
select order_id, d
from summary
where a > 0 and (b > 0 or c > 0)
Для каждого заказа, содержащего продукты A и не менее 2 * B, сообщите мне количества для A, B и C.
select order_id, a, b, c
from summary
where a > 0 and (a + b + c + d > 2 * b)
Я бы также обернул «сводку» в материализованное представление, если вы собираетесь запускать множество подобных сценариев, особенно с объемами данных, о которых вы говорите.
Если пример условный и на самом деле есть сотни номеров элементов или больше, то я бы пропустил CTE / view и построил каждый случай с соответствующим сценарием.
Я удалил несовместимые теги базы данных. Пожалуйста, укажите базу данных, которую вы действительно используете.