如何根据两个表的连接属性的最接近值对其左连接?

时间:2019-06-27 09:15:59

标签: sql sqlite left-join

假设我有两个表t1t2,它们的外观如下:

t1

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

t2

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

我正在尝试根据t1.valuet2.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 个答案:

答案 0 :(得分:1)

您可以这样做:

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
请参见demo
结果:

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

答案 1 :(得分:1)

使用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         

答案 2 :(得分:1)

我会推荐一个相关的子查询:

select t1.*,
       (select t2.value
        from t2
        where t2.id <= t1.id
        order by t2.id desc
        limit 1
       ) as t2_value
from t1;