Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to left-join two tables based on the closest value of their joining attributes?

Suppose I have two tables, t1 and t2, they look as follows:

t1:

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

t2:

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

I'm trying to left-join the two tables based on the minimum difference between t1.value and t2.value, such that the result contains all records of t1 with their closest matching partner from t2, so

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

I suppose the query would look something like this:

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

Here are the SQLite queries to reproduce the tables:

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);
like image 458
karpfen Avatar asked Nov 01 '25 03:11

karpfen


2 Answers

You can do it like this:

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)

You join on the absolute minimum of t1.value - t2.value.
See the demo.
Results:

| id  | value | id  |
| --- | ----- | --- |
| 1   | 1     | 1   |
| 2   | 1     | 1   |
| 3   | 2     | 2   |
| 4   | 12    | 3   |
| 5   | 13    | 3   |
like image 170
forpas Avatar answered Nov 03 '25 21:11

forpas


I would recommend a correlated subquery:

select t1.*,
       (select t2.value
        from t2
        where t2.id <= t1.id
        order by t2.id desc
        limit 1
       ) as t2_value
from t1;
like image 36
Gordon Linoff Avatar answered Nov 03 '25 20:11

Gordon Linoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!