2010-01-09 25 views
3

我有一個問題,我需要從一個列按列分組得到最早的日期值,但按順序分組SQL查詢找到依賴於列值更改的最早日期

下面是一個示例表:

if object_id('tempdb..#tmp') is NOT null 
    DROP TABLE #tmp 

CREATE TABLE #tmp 
(
    UserID    BIGINT  NOT NULL, 
    JobCodeID   BIGINT  NOT NULL, 
    LastEffectiveDate DATETIME NOT NULL 
) 

INSERT INTO #tmp VALUES (1, 5, '1/1/2010') 
INSERT INTO #tmp VALUES (1, 5, '1/2/2010') 
INSERT INTO #tmp VALUES (1, 6, '1/3/2010') 
INSERT INTO #tmp VALUES (1, 5, '1/4/2010') 
INSERT INTO #tmp VALUES (1, 1, '1/5/2010') 
INSERT INTO #tmp VALUES (1, 1, '1/6/2010') 

SELECT JobCodeID, MIN(LastEffectiveDate) 
FROM #tmp 
WHERE UserID = 1 
GROUP BY JobCodeID 

DROP TABLE [#tmp] 

這個查詢將返回3行,與所述最小值。

1 2010-01-05 00:00:00.000 
5 2010-01-01 00:00:00.000 
6 2010-01-03 00:00:00.000 

我所尋找的是該組按順序排列,並返回一個以上的JobCodeID,像這樣:

5 2010-01-01 00:00:00.000 
6 2010-01-03 00:00:00.000 
5 2010-01-04 00:00:00.000 
1 2010-01-05 00:00:00.000 

這是可能沒有遊標的情況?

回答

4
SELECT JobCodeId, MIN(LastEffectiveDate) AS mindate 
FROM (
     SELECT *, 
       prn - rn AS diff 
     FROM (
       SELECT *, 
         ROW_NUMBER() OVER (PARTITION BY JobCodeID 
            ORDER BY LastEffectiveDate) AS prn, 
         ROW_NUMBER() OVER (ORDER BY LastEffectiveDate) AS rn 
       FROM @tmp 
       ) q 
     ) q2 
GROUP BY 
     JobCodeId, diff 
ORDER BY 
     mindate 

連續範圍在分區和未分區ROW_NUMBERs之間有相同的區別。

您可以在GROUP BY中使用此值。

請參閱本文中我的博客更多的細節它是如何工作的:

+0

+1優雅的解決方案 – TheVillageIdiot 2010-01-09 17:28:14

1

第一條評論 - 使用表格變量而不是臨時表格會更好。然後你可以使用這樣的技巧。確保在正確的順序(即升序LastEffectiveDate)插入值:

DECLARE @tmp table 
(
    Sequence   INT IDENTITY, 
    UserID    BIGINT, 
    JobCodeID   BIGINT, 
    LastEffectiveDate DATETIME 
) 

INSERT INTO @tmp VALUES (1, 5, '1/1/2010') 
INSERT INTO @tmp VALUES (1, 5, '1/2/2010') 
INSERT INTO @tmp VALUES (1, 6, '1/3/2010') 
INSERT INTO @tmp VALUES (1, 5, '1/4/2010') 
INSERT INTO @tmp VALUES (1, 1, '1/5/2010') 
INSERT INTO @tmp VALUES (1, 1, '1/6/2010') 

SELECT TOP 1 JobCodeID, LastEffectiveDate 
FROM @tmp 

UNION ALL 

SELECT t2.JobCodeID, t2.LastEffectiveDate 
FROM @tmp t1 
    INNER JOIN 
     @tmp t2 
     ON t1.Sequence + 1 = t2.Sequence 
WHERE t1.JobCodeID <> t2.JobCodeID 

這每一次輸出的第一天工作碼變化,我猜你是從你的描述想要的東西。

+0

前請粘貼和運行註釋編輯 - ORDER BY被打破它。 – 2010-01-09 17:10:55

+0

臨時表代表現有的表,這就是我使用它的原因。我有一個需要利用查詢的實際表格。 – 2010-01-09 17:24:31