簡體   English   中英

根據一列的MAX和另一列的相關MIN選擇行

[英]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_timeinterval_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM