每组订购日期之间的平均天数

时间:2017-09-06 21:51:21

标签: sql sql-server sql-server-2012 average

+-------+-------+-----------+
| EmpID | PerID | VisitDate |
+-------+-------+-----------+
|     1 |    22 | 2/24/2017 |
|     1 |    22 | 3/25/2017 |
|     1 |    22 | 4/5/2017  |
|     2 |    33 | 5/6/2017  |
|     2 |    33 | 8/9/2017  |
|     2 |    33 | 6/7/2017  |
+-------+-------+-----------+

我正在尝试查找每个EmpID的最新访问日期和平均访问天数。对于Avg,我首先必须连续订购,然后找到平均值。

例如:平均EmpID = 1且PerID = 22的天数为[29(3/25至2/24之间的天数)+11(3/25至4/5之间的天数)/ 2] = 20天。

期望的输出:

+-------+-------+----------+----------+
| EmpID | PerID | MaxVDate | AvgVDays |
+-------+-------+----------+----------+
|     1 |    22 | 4/5/2017 |       20 |
|     2 |    33 | 8/9/2017 |     47.5 |
+-------+-------+----------+----------+

尝试:

SELECT
    EmpID
    ,PerID
    ,MAX(VisitDate) AS MaxVDate
    ,--Dunno how to find average AS AvgVDays

FROM
T1
GROUP BY
     EmpID
    ,PerID

3 个答案:

答案 0 :(得分:2)

您可以使用lag获取上一个日期并计算日期差异。然后使用avg窗口函数来获取平均天数。

Select distinct empid,perid,maxVdate,avg(diff_with_prev) OVER(Partition by empid) as avgVDays
from (
SELECT EmpID,PerID
,MAX(VisitDate) OVER(Partition BY EmpID) AS MaxVDate
,DATEDIFF(DAY,LAG(VisitDate) OVER(Partition BY EmpID order by VisitDate), VisitDate) as diff_with_prev
FROM T1
) t

答案 1 :(得分:1)

这项任务比你想象的容易得多。您可以获得(last visit - first visit) / (count visits - 1)的平均值。

select 
  empid, 
  perid, 
  max(VisitDate) as MaxVDate,
  datediff(day, min(VisitDate), max(VisitDate)) * 1.0 / (count(*) - 1) as avgvdays
from mytable
group by empid, perid
having count(*) > 1
order by empid, perid;

为了避免整数除法,需要乘以1.0。 (你也可以转而使用decimal。)

由于计算仅对具有多个条目的empid / perid对有意义(并且为了避免除以零),我已应用了相应的HAVING子句。

以下是测试:http://rextester.com/AIFPA62612

答案 2 :(得分:1)

这是一个选项......

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    EmpID INT NOT NULL,
    PerID INT NOT NULL,
    VisitDate DATE NOT NULL 
    );
INSERT #TestData (EmpID, PerID, VisitDate) VALUES
    (1, 22, '2/24/2017'),
    (1, 22, '3/25/2017'),
    (1, 22, '4/5/2017'),
    (2, 33, '5/6/2017'),
    (2, 33, '8/9/2017'),
    (2, 33, '6/7/2017');

-- SELECT * FROM #TestData td;

SELECT 
    db.EmpID,
    db.PerID,
    AvgDays = AVG(db.DaysBetween * 1.0)
FROM (
    SELECT 
        *,
        DaysBetween = DATEDIFF(dd, LAG(td.VisitDate, 1) OVER (PARTITION BY td.EmpID, td.PerID ORDER BY td.VisitDate), td.VisitDate)
    FROM
        #TestData td
    ) db
GROUP BY
    db.EmpID,
    db.PerID;

结果...

EmpID       PerID       AvgDays
----------- ----------- ---------------------------------------
1           22          20.000000
2           33          47.500000