SQL-запрос для объединения двух таблиц на основе ближайшей отметки времени - PullRequest
15 голосов
/ 01 ноября 2010

У меня есть две таблицы в SQL, и мне нужно иметь возможность выполнять объединение на основе отметки времени в таблице B, которая раньше или равна отметке времени в таблице A.

Итак, вотнекоторые поддельные данные для двух таблиц и желаемый результат:

Закрытые дела (таблица A)

| id | resolution |         timestamp          |
------------------------------------------------
|  1 |     solved | 2006-10-05 11:55:44.888153 |
|  2 |     closed | 2007-10-07 12:34:17.033498 |
|  3 |    trashed | 2008-10-09 08:19:36.983747 |
|  4 |     solved | 2010-10-13 04:28:14.348753 |

Классификация (таблица B)


| id |    value    |         timestamp          |
-------------------------------------------------
|  1 |    freshman | 2006-01-01 12:02:44.888153 |
|  2 |   sophomore | 2007-01-01 12:01:19.984333 |
|  3 |      junior | 2008-01-01 12:02:28.746149 |

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

| id | resolution |         timestamp          |    value    |
--------------------------------------------------------------
|  1 |     solved | 2006-10-05 11:55:44.888153 |    freshman |
|  2 |     closed | 2007-10-07 12:34:17.033498 |   sophomore |
|  3 |    trashed | 2008-10-09 08:19:36.983747 |      junior |
|  4 |     solved | 2010-10-13 04:28:14.348753 |      junior |

Итак, я знаю, что код должен выглядеть следующим образом, я просто не могу понять, что делать сON часть JOIN ($ 1 и $ 2 - переменные, которые будут переданы в):

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN classifications AS class ON ???
  WHERE case.timestamp BETWEEN $1 AND $2;

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

Ответы [ 3 ]

8 голосов
/ 01 ноября 2010

Если вы можете вносить изменения в структуры таблиц, я рекомендую изменить таблицу классификации, включив в нее дату окончания, а также дату начала - так будет легче присоединиться к таблице.Если нет, я предлагаю следующее:

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN (select c.*, 
                    (select min(timestamp)
                     from classifications c1
                      where c1.timestamp > c.timestamp) timeend
             from classifications c) AS class 
  ON case.timestamp >= class.timestamp and 
     (case.timestamp < class.timeend or class.timeend IS NULL)
  WHERE case.timestamp BETWEEN $1 AND $2;

РЕДАКТИРОВАТЬ - с датой окончания классификации:

SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN classifications AS class 
  ON case.timestamp >= class.timestamp and case.timestamp < class.timeend
  WHERE case.timestamp BETWEEN $1 AND $2;
0 голосов
/ 01 ноября 2010
SELECT case.id, case.resolution, case.timestamp, class.value
  FROM closed_cases AS case
  LEFT JOIN classifications AS class 
  ON case.timestamp >= class.timestamp
  WHERE case.timestamp BETWEEN $1 AND $2;
0 голосов
/ 01 ноября 2010

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

таблица 1 поле1 поле2 поле3 ConnectorField

таблица2 поле1 поле2 поле3 поле ConnectorField

, и все, что вам нужно сделать, это выбрать * из таблицы1 внутренняя T1присоединиться к table2 T2 на T1.ConnectorField = T2.ConnectorField

...