Найти ближайшую дату, сохраненную в другой таблице, в соответствии с несколькими «основными датами», общими данными, но без общего идентификатора - PullRequest
0 голосов
/ 09 мая 2019

Извините за название, это было довольно сложно объяснить в нескольких словах (это показывает, что я не полностью понимаю проблему).

Service Table: (there are other field but not relevant here)
-------------------------------
| PK1    | REF     | Ops_Date |
-------------------------------
| 1      | ABCD    | 20180211 |
| 2      | EFGH    | 20180315 |
| 3      | ABCD    | 20180412 |
-------------------------------

Dim Table: 
-------------------------------
| PK2    | REF     | Arrival  |
-------------------------------
| 57     | ABCD    | 20180108 |
| 58     | ABCD    | 20180201 |
| 59     | EFGH    | 20180309 |
| 60     | EFGH    | 20180311 |
| 61     | ABCD    | 20180409 |
| 62     | ABCD    | 20180411 |
-------------------------------

Result:
--------------------------------------------------------
| PK1    | REF     | Ops_Date | PK2      | Arrival     |       
--------------------------------------------------------
| 1      | ABCD    | 20180211 | 58       | 20180201    |
| 2      | EFGH    | 20180315 | 60       | 20180311    | 
| 3      | ABCD    | 20180412 | 62       | 20180411    |
--------------------------------------------------------

Мне нужно левое соединение служебной таблицы с таблицей dim. Критериями ON являются REF, который является общим для обоих, а затем ближайший приход из ops_date. Дата ops всегда будет после прибытия, это то, что мне нужно, всегда самое близкое до ops_date.

Что я пытаюсь:

   SELECT 
      PK1, 
      REF,
      ops_date, 
      PK2, 
      arrival

   FROM 
     service 

   LEFT JOIN dim
   ON service.REF = dim.REF

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

Я не уверен, что такое мышление возможно даже без каких-либо ETL или процедур, но если у кого-то есть подсказка, это будет высоко оценено.

Заранее спасибо за помощь.

1 Ответ

1 голос
/ 09 мая 2019

Вам просто нужно добавить к вашему JOIN условие, которое говорит, что Arrival время в Dim - это максимальное Arrival время, которое меньше соответствующего Ops_Date значения для этого Service.Этот результат можно найти с помощью коррелированного подзапроса:

SELECT s.*, d.PK2, d.Arrival
FROM Service s
LEFT JOIN Dim d ON d.REF = s.REF 
               AND d.Arrival = (SELECT MAX(Arrival)
                                FROM Dim d2
                                WHERE d2.REF = s.REF
                                  AND d2.Arrival < s.Ops_Date)

Вывод:

PK1 REF     Ops_Date    PK2 Arrival
1   ABCD    20180211    58  20180201
2   EFGH    20180315    60  20180311
3   ABCD    20180412    62  20180411

Демонстрация на dbfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...