Логика запросов, необходимо предложение решения - PullRequest
0 голосов
/ 23 февраля 2019

http://sqlfiddle.com/#!17/e9c97/59

Вот моя примерная база данных.Таблицы, созданные с помощью WITH, являются упрощенными версиями, в случае, если я работаю, статус is_paid - это множество других условий, поэтому его нельзя просто использовать из таблицы orders.Но вывод тот же

Что я хочу сделать, так это найти детали первого заказа (min(order_id)), где все заказы клиента НЕ были оплачены ИЛИ min(order_id) для неоплаченного заказа меньше, чем min(order_id) для оплаченногопорядок.

Простота: клиент с оплаченным заказом до неоплаченного заказа исключен из результатов.

having min(onp.order_id) < min(op.order_id) эта часть бессмысленна без итерации внутри заказов одного customer_id, но как это сделать?

Чем дольше я думаю о решении, тем меньше логических способов я пытаюсь ..

Ожидаемый результат должен быть:

order_id, customer_id, amount
3         101          30
5         102          15
11        104          31
15        105          11

1 Ответ

0 голосов
/ 23 февраля 2019

Я полагаю, что следующий запрос должен выполнить задание:

SELECT * FROM (
    SELECT o.*, 
        MAX(is_paid) OVER(PARTITION BY customer_id ORDER BY order_id) mp, 
        ROW_NUMBER() OVER(PARTITION BY customer_id, is_paid ORDER BY order_id) rn
    FROM orders o
) x WHERE is_paid = 0 AND rn = 1 AND mp = 0

Запрос использует подзапрос с оконными функциями для:

  • проверки, был ли оплачен какой-либо предыдущий заказдля этого клиента: MAX(is_paid) OVER(...)
  • назначить порядковый номер каждой записи в группах клиентов / статусов: ROW_NUMBER() OVER(...)

Когда не существует предшествующего оплаченного заказа, и это первыйнеоплачиваемая запись, затем запись фильтруется внешним запросом:

Демонстрация на БД Fiddle :

| order_id | customer_id | amount |
| -------- | ----------- | ------ |
| 3        | 101         | 30     |
| 5        | 102         | 15     |
| 11       | 104         | 31     |
| 15       | 105         | 11     |
...