条件聚合查询

时间:2012-02-20 19:32:17

标签: sql sql-server sql-server-2008

我有一张这样的表:

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

我一直在圈子里跑来跑去,想出了条件聚合查询这个问题。

有人可以弄清楚查询或给我一些指示吗?

2 个答案:

答案 0 :(得分: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

编辑参考a.MaxTimestamp

答案 1 :(得分:0)

  1. 按时间戳排序每个订单的阶段。

  2. 根据排名加入每一行及其后续行。

  3. 标记PhaseID后跟较小PhaseID的行。

  4. 使用MAX(CASE ...)有条件地聚合最后一个结果集选择最大时间戳,以省略标记为次要较小PhaseID的行。

  5. 以下是一个示例实现:

    ;
    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