SQL-условие, охватывающее несколько строк

Я работаю над системой заказа на основе базы данных PostgreSQL, поэтому у меня есть таблица OrderLines следующего вида:

order_id     int
product_id   int
quantity     int

Затем каждый заказ состоит из одной строки в этой таблице для каждого уникального заказанного продукта.

Я пытаюсь выполнить запросы вида:

  • Для каждого заказа, содержащего продукты A, B и C, укажите количество продуктов C и D.
  • Для каждого заказа, содержащего продукты A и (B или C), дайте мне количество продукта D
  • Для каждого заказа, содержащего продукты A и не менее 2 * B, сообщите мне количества для A, B и C.

Условие здесь потенциально может иметь глубоко вложенные предложения. Заказов могут быть миллионы, а в заказе более 10 тыс. Строк. Условия не могут быть известны заранее. Если товара нет в заказе, его количество необходимо вернуть как 0.

Есть ли у вас какие-либо указания относительно написания запросов с условиями, охватывающими несколько строк, например этой?

Я удалил несовместимые теги базы данных. Пожалуйста, укажите базу данных, которую вы действительно используете.

Gordon Linoff 17.12.2018 19:34

Готово. PostgreSQL.

Pierre 17.12.2018 19:35
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
2
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать условное агрегирование. Например, для первого:

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 и построил каждый случай с соответствующим сценарием.

Другие вопросы по теме