[英]Can you get a different column from a row with a MIN or MAX value?
I'm building an application with millions of rows, so I'm trying to avoid JOIN whenever possible.我正在构建一个包含数百万行的应用程序,因此我尽可能避免使用 JOIN。 I have a table like this:
我有一张这样的表:
ID category value_1 value_2
1 1 2.2432 5.4321
2 2 6.5423 5.1203
3 1 8.8324 7.4938
4 2 0.4823 9.8244
5 2 7.2456 3.1278
6 1 1.9348 4.4421
I'm trying to retrieve value_1
from the row with the lowest ID
and value_2
from the row with the highest ID while grouped by category
, like this:我正在尝试从
ID
最低的行中检索value_1
从ID
最高的行中检索value_2
,同时按category
分组,如下所示:
category value_1 value_2
1 2.2432 4.4421
2 6.5423 3.1278
Is this possible in an effective way while avoiding constructs like string operations and JOIN?在避免字符串操作和 JOIN 之类的构造的同时,这是否可能以一种有效的方式实现?
Thank you!谢谢!
Try this:尝试这个:
SELECT
category,
(
SELECT t2.value1
FROM table1 t2
WHERE t2.id = MIN(t1.id)
) as value1,
(
SELECT t3.value2
FROM table1 t3
WHERE t3.id = MAX(t1.id)
) as value2
FROM
table1 t1
GROUP BY
category
;
Create and fill table:创建和填充表:
CREATE TABLE `table1` (
`id` INT NOT NULL,
`category` INT NULL,
`value1` DOUBLE NULL,
`value2` DOUBLE NULL,
PRIMARY KEY (`id`)
);
INSERT INTO table1 VALUES
(1, 1, 2.2432, 5.4321),
(2, 2, 6.5423, 5.1203),
(3, 1, 8.8324, 7.4938),
(4, 2, 0.4823, 9.8244),
(5, 2, 7.2456, 3.1278),
(6, 1, 1.9348, 4.4421);
Output:输出:
1 2.2432 4.4421
2 6.5423 3.1278
One approach which avoids joins is to use ROW_NUMBER
:避免连接的一种方法是使用
ROW_NUMBER
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY category ORDER BY ID) rn_min,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY ID DESC) rn_max
FROM yourTable
)
SELECT
category,
MAX(CASE WHEN rn_min = 1 THEN value_1 END) AS value_1,
MAX(CASE WHEN rn_max = 1 THEN value_2 END) AS value_2
FROM cte
GROUP BY
category;
Edit:编辑:
The above query should benefit from the following index:上述查询应受益于以下索引:
CREATE INDEX idx ON yourTable (category, ID);
This should substantially speed up the row number operations.这应该会大大加快行号操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.