SQL получить ближайшее значение по дате - PullRequest
1 голос
/ 27 марта 2020

не могу обдумать следующую проблему. У меня есть таблица с историческими данными TableA:

uniq_id item_id item_clust date
11111   1       a          2020-02-12
11112   1       a          2020-01-13
11113   1       b          2020-02-01
11114   2       b          2020-01-01

У меня также есть таблица с историческими данными для кластеров TableB:

item_id item_clust item_pos date
1       a          1        2020-01-01
1       a          2        2020-02-01
1       a          3        2020-03-01
1       b          1        2020-01-10

Я хотел бы получать самую последнюю позицию для каждой item_id + item_clust для даты, основанной на датах в TableB Если строк не найдено, я хотел бы вставить item_pos = 0

Желаемый результат:

uniq_id item_id item_clust date       item_pos
11111   1       a          2020-02-12 2
11112   1       a          2020-01-13 1
11113   1       b          2020-02-01 1
11114   2       b          2020-01-01 0

Итак, для item 1 в cluster a в 2020-02-12 последняя позиция в 2020-02-01 = 2.

1 Ответ

2 голосов
/ 27 марта 2020

Это выглядит как left join:

select a.*, coalesce(b.item_pos, 0) as item_pos
from a left join
     (select distinct on (b.item_id, b.item_clust) b.*
      from b
      order by b.item_id, b.item_clust, b.date desc
     ) b
     using (item_id, item_clust);

или боковое соединение:

select a.*, coalesce(b.item_pos, 0) as item_pos
from a left join lateral
     (select b.*
      from b
      where b.item_id = a.item_id and
            b.item_clust = a.item_clust
      order by b.date desc
      limit 1
    ) b
    on true;  -- always do the left join even when there are no matches

РЕДАКТИРОВАТЬ:

Если вы хотите самую последнюю позицию " на дату A, затем используйте боковое соединение:

select a.*, coalesce(b.item_pos, 0) as item_pos
from a left join lateral
     (select b.*
      from b
      where b.item_id = a.item_id and
            b.item_clust = a.item_clust and
            b.date <= a.date
      order by b.date desc
      limit 1
    ) b
    on true;  -- always do the left join even when there are no matches
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...