2017-09-06 13 views
0
+-------+-------+-----------+ 
| 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 

答えて

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 
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 
+0

これはのEmpIDの平均日数として13と31を与えているようですそれぞれ1および2である。 20および47.5ではない。外部の平均関数には計算に0が含まれているため、効果的に3を超えて2を平均で計算していません。 – AS91

+0

LAGのデフォルトのVisitDateを削除すると、あなたの解決策の秘訣は – AS91

+0

@ AS91 ..あなたは正しい答えを編集しています。 –

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に代わってキャストすることもできます)

計算は2つ以上のエントリを持つempid/peridのペアにのみ意味があります(ゼロ除算を避けるため)。HAVING句を適用しました。ここで

はテストです:http://rextester.com/AIFPA62612