我试图对不同的行数据进行平均,如下所示。
所以基本上这是桌子
create table t (id int identity, BIDID int, AppID int, AppStatus varchar(20), [Time] date);
insert into t values
(23390, 16, 'In Review', '20170307'),
(23390, 16, 'Approved', '20170309'),
(23390, 16, 'In Review', '20171110'),
(23390, 16, 'Approved', '20171112'),
(23390, 17, 'In Review', '20171114'),
(23390, 18, 'Approved', '20171112'),
(23390, 16, 'Approved', '20171114'),
(23391, 17, 'In Review', '20171112'),
(23391, 17, 'Approved', '20171114')
我尝试仅首先在单个AppID之间计算In Review和Approved值之间的平均值,然后在单个出价中对不同AppId进行平均值计算,然后最后在所有出价之间求平均值以得出一个数字
这是代码
SELECT
CASE WHEN t1.AppStatus = 'In Review' AND t2.AppStatus = 'Approved'
THEN DATEDIFF(day, t1.[Time], t2.[Time])
ELSE 0
END as Days
FROM
t t1
CROSS APPLY(SELECT TOP 1 *
FROM t
WHERE id > t1.id
ORDER BY id) t2
这让我得到了平均值
WITH ct AS
(
SELECT
CASE WHEN t1.AppStatus = 'In Review' AND t2.AppStatus = 'Approved'
THEN DATEDIFF(day, t1.[Time], t2.[Time])
ELSE 0
END as Days
FROM
t t1
CROSS APPLY(SELECT TOP 1 *
FROM t
WHERE id > t1.id
ORDER BY id) t2
)
SELECT
SUM(days) / COUNT(*) Average
FROM
ct
WHERE
days <> 0
此操作目前不进行任何形式的分组,因此仅将“审核中”考虑在内,然后查找下一个“批准”,依此类推。我需要先按AppID对其进行分组,以计算各个AppId的平均值,然后对出价内不同AppId的平均值进行平均,然后对出价的平均值进行
有人可以告诉我如何添加分组。
预期结果
(1 23390, 16, 'In Review', '20170308'),
(2 23390, 16, 'Approved', '20170309'),
(3 23390, 16, 'In Review', '20171110'),
(4 23390, 16, 'Approved', '20171112'),
(5 23390, 17, 'In Review', '20171114'),
(6 23390, 18, 'In Review', '20171112'),
(7 23390, 16, 'Approved', '20171114'),
(8 23391, 17, 'In Review', '20171112'),
(9 23391, 17, 'Approved', '20171114')
23390 AppID16 FirstData Id1 to Id2 1Day (In Review -> Approved)
23390 AppID16 SecondData Id3 to Id4 2Day
23390 AppID16 ThirdData Id7 Ignored Since no In Review Before..
Avg AppID 16 = 1.5 days
23390 AppID 17 ignored since no Approved after in review
23390 AppID 18 Ignored
Avg for 23390 = 1.5
..类似地计算其他出价的平均值
23391 AppID 17天2。
因此,两次出价之间的平均总和为2 + 1.5 / 2
谢谢
答案 0 :(得分:1)
这是一种方法。非常简单。每个步骤都包裹在CTE中。检查每个CTE的中间结果,以了解其工作原理并查看代码中的注释。
样本数据
create table t (id int identity, BIDID int, AppID int, AppStatus varchar(20), dt date);
insert into t values
(23390, 16, 'In Review', '20170308'),
(23390, 16, 'Approved', '20170309'),
(23390, 16, 'In Review', '20171110'),
(23390, 16, 'Approved', '20171112'),
(23390, 17, 'In Review', '20171114'),
(23390, 18, 'Approved', '20171112'),
(23390, 16, 'Approved', '20171114'),
(23391, 17, 'In Review', '20171112'),
(23391, 17, 'Approved', '20171114');
查询
我调整了您的CROSS APPLY
,使其与问题中描述的逻辑相符。
WITH
-- Find matching pairs and calculate the difference of individual dates
CTE_Diffs
AS
(
SELECT
MainT.id
,MainT.BIDID
,MainT.AppID
,CAST(DATEDIFF(day, MainT.dt, NextT.dt) AS float) AS Diff
FROM
T AS MainT
CROSS APPLY
(
SELECT TOP 1
T.AppStatus
,T.dt
FROM T
WHERE
-- the matching row must be from the same Bid and App
-- and have a higher ID
T.BIDID = MainT.BIDID
AND T.AppID = MainT.AppID
AND T.id > MainT.id
ORDER BY
T.id
) AS NextT
WHERE
-- the pair is counted only when it starts with 'In Review' and finishes with 'Approved'
MainT.AppStatus = 'In Review'
AND NextT.AppStatus = 'Approved'
)
-- Average by Bid and App
,CTE_AvgBidApp
AS
(
SELECT
BIDID
,AppID
,AVG(Diff) AS AvgBidApp
FROM CTE_Diffs
GROUP BY
BIDID
,AppID
)
-- Average by Bid
,CTE_AvgBid
AS
(
SELECT
BIDID
,AVG(AvgBidApp) AS AvgBid
FROM CTE_AvgBidApp
GROUP BY
BIDID
)
-- Final average
SELECT
AVG(AvgBid) AS TotalAvg
FROM CTE_AvgBid
;
结果
TotalAvg
1.75
清理
DROP TABLE t;