我的表格结构如下。我想知道是否可以通过TransactionID压缩每个事务,从第一行和最后一行拉取值,然后最终计算事务的持续时间。
例如下面,我想拉RecordID和CustomerID。然后别名一个名为startingStatus的新列,该列将从第一行“提交”。我将别名第二列名为endingStatus,该列将是最后一行的“Success”。然后我需要以相同的方式获取时间戳,创建startingTime和endingTime。最后一列是开始和结束之间的差异。
RecordID TransactionID CustomerID Status TimeStamp
1 12 10 Submitted 04/07/2014 14:32:23
2 12 10 Queued 04/07/2014 14:32:24
3 12 10 Processing 04/08/2014 14:32:26
4 12 10 Error 04/09/2014 14:32:27
5 12 10 Resubmitted 04/10/2014 15:12:29
6 12 10 Queued 04/11/2014 15:12:31
7 12 10 Processing 04/12/2014 15:12:34
8 12 10 Success 04/13/2014 15:12:47
我一直试图通过TransactionID进行分组并使用MIN和MAX,但我还没有让它工作。
我将如何做这样的事情?
答案 0 :(得分:1)
尝试一下:
SELECT
CustomerID,
TransactionID,
Min([TimeStamp]) as StartTime,
Max([TimeStamp]) as EndTime,
DATEDIFF(MINUTE,Min([TimeStamp]),Max([TimeStamp])) as TransactionTime
FROM YourTable
GROUP BY CustomerID, TransactionID
ORDER BY CustomerID, TransactionID
答案 1 :(得分:1)
我会使用窗口函数来检索组的第一个和最后一个记录。
这将适用于SQL Server 2005及更高版本,方法是使用ROW_NUMBER()窗口函数,然后使用MAX / CASE WHEN方法旋转结果:
SELECT
[TransactionID],
[CustomerID],
MAX(CASE WHEN [rn_asc] = 1 THEN [Status] ELSE NULL END) [startingStatus],
MAX(CASE WHEN [rn_desc] = 1 THEN [Status] ELSE NULL END) [endingStatus],
MAX(CASE WHEN [rn_asc] = 1 THEN [TimeStamp] ELSE NULL END) [startingTimeStamp],
MAX(CASE WHEN [rn_desc] = 1 THEN [TimeStamp] ELSE NULL END) [endingTimeStamp],
DATEDIFF(
SECOND,
MAX(CASE WHEN [rn_asc] = 1 THEN [TimeStamp] ELSE NULL END),
MAX(CASE WHEN [rn_desc] = 1 THEN [TimeStamp] ELSE NULL END)
) [duration]
FROM
(
SELECT
[TransactionID],
[CustomerID],
ROW_NUMBER() OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] ASC) [rn_asc],
ROW_NUMBER() OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] DESC) [rn_desc],
[Status],
[Timestamp]
FROM [tbl]
) A
GROUP BY
[TransactionID],
[CustomerID]
SQL Server 2012引入了FIRST_VALUE函数,因此如果您运行的是该版本,则可以考虑此查询
SELECT DISTINCT
[TransactionID],
[CustomerID],
FIRST_VALUE([Status]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] ASC) [startingStatus],
FIRST_VALUE([Status]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] DESC) [endingStatus],
FIRST_VALUE([TimeStamp]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] ASC) [startingTimeStamp],
FIRST_VALUE([TimeStamp]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] DESC) [endingTimeStamp],
DATEDIFF(
SECOND,
FIRST_VALUE([TimeStamp]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] ASC),
FIRST_VALUE([TimeStamp]) OVER (PARTITION BY [TransactionID], [CustomerID] ORDER BY [RecordID] DESC)
) [duration]
FROM [tbl]