2012-02-20 150 views
2

我有這樣的一個表:條件彙總查詢

OrderID | PhaseID | Timestamp 
1  | 1  | 1/1 
1  | 2  | 1/2 
1  | 3  | 1/3 
1  | 2  | 1/4 
1  | 4  | 1/5 

我試圖讓一個查詢返回最近的每個orderphase組合時間戳不被隨後較小phaseid。這樣的事情:

OrderID | PhaseID | MaxTimestampWithoutBeingFollowedByLesserPhaseID 
1  | 1  | 1/1 
1  | 2  | 1/4 
1  | 3  | NULL 
1  | 4  | 1/5 

我一直在圈出來跑來跑去,並想出這個問題的條件聚合查詢。

任何人都可以找出查詢或給我一些指針嗎?通過爲每一個順序的時間標記

+1

你的意思是下一行是一個較小的階段ID,或者說有一個更高的時間戳不小的階段IDS? – JNK 2012-02-20 19:39:05

+2

對於預期的輸出可能是一個標尺更多的幫助..一行是不夠真實的你的問題 – Randy 2012-02-20 19:39:41

+2

你也只是懶惰的樣本數據,或者你實際上有'1/1'作爲一個「時間郵票」? – JNK 2012-02-20 19:40:42

回答

0
With a as (
Select OrderID, PhaseID, MaxTimestamp=max([Timestamp]) 
From orderphase op 
Where not exists(select 1 from orderphase where PhaseID < op.PhaseID 
    and [Timstamp]> op.[Timestamp]) 
Group by OrderID, PhaseID 
) 
Select distinct o.Orderid, o.PhaseID, MaxTimestamp=a.MaxTimestamp 
From orderphase o 
Left join a on a.OrderID = o.OrderID and a.PhaseID=o.PhaseID 

EDIT REF a.MaxTimestamp

+0

這裏'JOIN'的點是什麼? – JNK 2012-02-20 19:57:41

+0

@JNK - 在結果中提供空時間戳,其中階段之後是較少的階段。 – 2012-02-20 20:04:36

+1

從OP聽起來他只是想要匹配的結果,而不是其他。同樣對於你的查詢,你應該使用'a.MaxTimeStamp',因爲你寫的字段名不對齊。 – JNK 2012-02-20 20:07:46

0
  1. 等級相。

  2. 根據等級加入每一行及其後繼者。

  3. 標記PhaseID後跟PhaseID後面的行。

  4. 使用MAX(CASE ...)有條件地聚合最後的結果集挑選最大時間戳,以省略標記爲較少的PhaseID後面的行。

這裏是一個示例實現:

; 
WITH ranked AS (
    SELECT 
    *, 
    rnk = ROW_NUMBER() OVER (PARTITION BY OrderID ORDER BY [Timestamp]) 
    FROM atable 
), 
marked AS (
    SELECT 
    r1.OrderID, 
    r1.PhaseID, 
    r1.[Timestamp], 
    IsFollowedByLesserPhaseID = CASE WHEN r2.PhaseID IS NULL THEN 0 ELSE 1 END 
    FROM ranked r1 
    LEFT JOIN ranked r2 ON r1.OrderID = r2.OrderID 
         AND r1.rnk  = r2.rnk - 1 
         AND r1.PhaseID > r2.PhaseID 
) 
SELECT 
    OrderID, 
    PhaseID, 
    MaxTimestampWithoutBeingFollowedByLesserPhaseID = MAX(
    CASE IsFollowedByLesserPhaseID WHEN 0 THEN [Timestamp] END 
) 
FROM marked 
GROUP BY 
    OrderID, 
    PhaseID