Как объединить две таблицы влево на основе ближайшего значения их атрибутов соединения? - PullRequest
2 голосов
/ 27 июня 2019

Предположим, у меня есть две таблицы t1 и t2, они выглядят следующим образом:

t1:

id, value
1, 1
2, 1
3, 2
4, 12
5, 13

t2:

id, value
1, 1
2, 2
3, 10

Я пытаюсь объединить две таблицы слева, исходя из минимальной разницы между t1.value и t2.value, так что результат содержит все записи t1 с ближайшим соответствующим партнером из t2, поэтому

t1.id, t1.value,t2.id
1,1,1
2,1,1
3,2,2
4,12,3
5,13,3

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

SELECT t1.id, t1.value, t2.id
FROM t1 LEFT JOIN t2
ON t1.value = t2.value -- I don't know what to do here

Вот SQLite-запросы для воспроизведения таблиц:

CREATE TABLE "t1" ( "id" INTEGER, "value" INTEGER);
CREATE TABLE "t2" ( "id" INTEGER, "value" INTEGER);
INSERT INTO t1 VALUES (1, 1), (2, 1), (3, 2), (4, 12), (5, 13);
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 10);

Ответы [ 3 ]

1 голос
/ 27 июня 2019

Вариант, использующий оконные функции, добавленные в Sqlite 3.25 вместо коррелированного подзапроса:

WITH cte(id, value, id2, rnk) AS
 (SELECT t1.id, t1.value, t2.id
       , rank() OVER (PARTITION BY t1.id ORDER BY abs(t1.value - t2.value))
  FROM t1
  LEFT JOIN t2)
SELECT id, value, id2
FROM cte
WHERE rnk = 1
ORDER BY id;

, что дает

id          value       id2       
----------  ----------  ----------
1           1           1         
2           1           1         
3           2           2         
4           12          3         
5           13          3         
1 голос
/ 27 июня 2019

Я бы порекомендовал коррелированный подзапрос:

select t1.*,
       (select t2.value
        from t2
        where t2.id <= t1.id
        order by t2.id desc
        limit 1
       ) as t2_value
from t1;
1 голос
/ 27 июня 2019

Вы можете сделать это так:

SELECT t1.id, t1.value, t2.id
FROM t1 LEFT JOIN t2
ON abs(t1.value - t2.value) = (select min(abs(t1.value - value)) from t2)

Вы присоединяетесь к абсолютному минимуму t1.value - t2.value.Смотрите демо .Результаты:

| id  | value | id  |
| --- | ----- | --- |
| 1   | 1     | 1   |
| 2   | 1     | 1   |
| 3   | 2     | 2   |
| 4   | 12    | 3   |
| 5   | 13    | 3   |
...