#postgresql
#postgresql
Вопрос:
Кажется, что это должно быть просто, но мне не хватает некоторых знаний о соединениях.
Предположим, у меня есть две таблицы:
bi_view_in_invoices payments
id due_date id payment_system_paid_date
1 2020-01-15 1 2020-01-16
2 2020-02-13 2 2020-01-10
3 2020-03-01 2 2020-02-19
4 2020-03-02 3 2020-02-11
3 2020-03-03
4 2020-02-11
Я хочу объединить эти две таблицы по id: чтобы вернуть due_date из Table1 и вернуть payment_system_paid_date из Table2 только в том случае, если он находится между одним днем до due_date и тремя днями позже. Иначе он должен возвращать значение null.
Это должно выглядеть так:
Result:
id due_date payment_system_paid_date
1 2020-01-15 2020-01-16
2 2020-02-13 null
3 2020-03-01 2020-03-03
4 2020-03-02 null
Я попробовал этот SQL:
select bvii.id, bvii.due_date, h1.pd, *
from bi_view_in_invoices bvii
left join payments p
on bvii.id = p.id
inner join (
select bvii.number, min(p.payment_system_paid_date) as pd
from bi_view_in_invoices bvii
left join payments p
on bvii.id = p.id
where p.payment_system_paid_date >= (bvii.due_date - 1)
and p.payment_system_paid_date <= (bvii.due_date 3)
group by bvii.number
) h1
on bvii.number = h1.number
and p.payment_system_paid_date = h1.pd
Он возвращает мне только эти идентификаторы, которые имеют дату, и не возвращает нулевые значения.
Мой результат выглядит так:
id due_date payment_system_paid_date
1 2020-01-15 2020-01-16
3 2020-03-01 2020-03-03
Не могли бы вы посоветовать мне, что я делаю не так?
Я также пытался добавить:
или p.payment_system_paid_date не равен нулю, а h1.pd равен нулю
но, похоже, это тоже не работает.
Спасибо!
Комментарии:
1. Должно быть
... left join payments p on (bvii.id = p.id and p.payment_system_paid_date >= (bvii.due_date - 1) and p.payment_system_paid_date <= (bvii.due_date 3)) group by bvii.number ...
2. кажется, это работает! еще одна проблема: мне действительно нужно использовать еще несколько столбцов из моих таблиц, и я не могу использовать group by, так как тогда все столбцы в select должны использоваться в агрегатной функции. Есть ли способ решить эту проблему?
3. Это еще один, другой вопрос.
Ответ №1:
with t1(x,y) as (values(1,10),(2,20)), t2(x,y) as (values(1,12),(2,18))
select *
from t1 left join t2 on (t1.x = t2.x)
where t1.y < t2.y;
┌───┬────┬───┬────┐
│ x │ y │ x │ y │
├───┼────┼───┼────┤
│ 1 │ 10 │ 1 │ 12 │
└───┴────┴───┴────┘
with t1(x,y) as (values(1,10),(2,20)), t2(x,y) as (values(1,12),(2,18))
select *
from t1 left join t2 on (t1.x = t2.x and t1.y < t2.y);
┌───┬────┬──────┬──────┐
│ x │ y │ x │ y │
├───┼────┼──────┼──────┤
│ 1 │ 10 │ 1 │ 12 │
│ 2 │ 20 │ ░░░░ │ ░░░░ │
└───┴────┴──────┴──────┘
where
условие здесь понижается left join
до inner join
неявного.