希望这是一个简单的问题,我只是想错了。
我在id_1
和id_2
之间有联系.id_1
和id_2
之间存在 1->n 的关系。也就是说,如果不存在id_1
id_2
则其默认值为 -1。这可能看起来像:
id_1 id_2 info
---- | ---- | ----
120 -1 'dont'
120 444 'show'
123 -1 'test'
124 -1 'hello'
125 -1 'world'
125 123 'oh wait'
126 -1 'help'
126 201 'me'
127 -1 'sql'
127 206 'hell'
基本上,我希望有一个SQL查询,该查询获得与id_1
关联的最高id_2
,给定与id_1
条件匹配的IN
语句。如果我不能有一个IN
语句,那也很好,我只是在尝试优化其他东西。
以下是给定包含(123,124,125,126,127)
id_1
和包含(-1,-1,123,201,206)
id_2
的答案应该是什么样子:
id_1 id_2 info
---- | ---- | ----
123 -1 'test'
124 -1 'hello'
125 123 'oh wait'
126 201 'me'
127 206 'hell'
请注意id_1
120
最终是如何被排除的。我试过:
SELECT DISTINCT id_1, id_2, info
FROM ids
WHERE
id_1 IN (123, 124, 125, 126, 127) AND
id_2 IN (-1, -1, 123, 201, 206)
但这为单个id_1
提供了多个id_2
值。
我也尝试了id_2
GROUP BY
,但这只给了我一个 -1 的id_1
。
SELECT id_1, id_2, info
FROM ids
WHERE
id_1 IN (123, 124, 125, 126, 127) AND
id_2 IN (-1, -1, 123, 201, 206)
GROUP BY id_2
结果在:
id_1 id_2 info
----- | ---- | ----
123 -1 'test'
125 123 'oh wait'
126 201 'me'
127 206 'hell'
请注意缺少124
id_1
。
那么,如何编写此查询以获取id_1
的最新、不同的id_2
呢?
如果在MySQL 8+ 上,您可以使用ROW_NUMBER
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id_1 ORDER BY id_2 DESC) rn
FROM ids
WHERE id_1 IN (123, 124, 125, 126, 127) AND
id_2 IN (-1, -1, 123, 201, 206)
)
SELECT id_1, id_2, info
FROM cte
WHERE rn = 1;
在早期版本的 MySQL 上,您可以使用存在逻辑识别每个id_1
组的最大记录数:
SELECT i1.*
FROM ids i1
WHERE id_1 IN (123, 124, 125, 126, 127) AND
id_2 IN (-1, -1, 123, 201, 206) AND
NOT EXISTS (
SELECT 1
FROM ids i2
WHERE i2.id_1 = i1.id_1 AND
i2.id_2 > i1.id_2 AND
i2.id_1 IN (123, 124, 125, 126, 127) AND
i2.id_2 IN (-1, -1, 123, 201, 206)
);