![](/img/trans.png)
[英]Select min of one column, max of another column and fields that go with max
[英]Select row based upon the MAX of one column and the related MIN of another
我有一个这样的表:
CREATE TABLE dbo.IntervalCounts (
item_id int NOT NULL,
interval_time time(0) NOT NULL,
interval_count int DEFAULT 0 NOT NULL
)
每个item_id具有96个interval_time ,从00:00到23:45以15分钟为增量。 每个interval_time的interval_count > = 0。 2亿行。
我需要从计数最高的表中选择值,然后,如果有多个具有相同计数的合格行,则选择间隔时间最短的行。
因此,如果我有一个item_id 1,其最大计数为100:
item_id interval_time interval_count
1 00:00 100
1 13:15 100
1 07:45 100
1 19:30 100
我只想排一行:
item_id interval_time interval_count
1 00:00 100
获得第一选择很容易,我得到了:
SELECT a.item_id, a.interval_time, a.interval_count
FROM dbo.IntervalCounts a
LEFT JOIN dbo.IntervalCounts b
ON a.item_id = b.item_id
AND a.interval_count < b.interval_count
WHERE 1=1
AND b.interval_count IS NULL
但是,对我来说,将其降低到仅一排是很棘手的。
在我杀死它之前,这种三重自我连接运行了一个半小时(我将定期运行它,理想情况下,它最多运行不超过15分钟)。
SELECT a.item_id, a.interval_time, a.interval_count
FROM dbo.IntervalCounts a
LEFT JOIN dbo.IntervalCounts b
ON a.item_id = b.item_id
AND a.interval_count < b.interval_count
LEFT JOIN dbo.IntervalCounts c
ON a.item_id = c.item_id
-- if I remove this line, it will ALWAYS give me the 00:00 interval
-- if I keep it, it runs way too long
AND a.interval_count = c.interval_count
AND a.interval_time > c.interval_time
WHERE 1=1
AND b.interval_count IS NULL
AND c.interval_time IS NULL
像这样做起来似乎很费劲,而且我也被迫在大约一个半小时后终止执行:
DECLARE @tempTable TABLE
(
item_id int,
interval_time time(0),
interval_count int
)
INSERT INTO @tempTable
SELECT a.item_id, a.interval_time, a.interval_count
FROM dbo.IntervalCount a
LEFT JOIN dbo.IntervalCount b
ON a.item_id = b.item_id
AND a.interval_count < b.interval_count
WHERE 1=1
AND b.interval_count IS NULL
SELECT a.item_id, a.interval_time, a.interval_count
FROM @tempTable a
LEFT JOIN @tempTable b
ON a.item_id = b.item_id
AND a.interval_time > b.interval_time
WHERE 1=1
AND b.interval_time IS NULL
一定有更好的方法,但是我很沮丧。 如何以一种不会永远运行的方式来做到这一点?
您想得太多了,可以使用ROW_NUMBER
:
WITH CTE AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY item_id
ORDER BY interval_count DESC, interval_time)
FROM dbo.IntervalCounts
)
SELECT *
FROM CTE
WHERE RN = 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.