Использование SQL Server 2012, как перебирать неизвестное количество строк и вычислять разницу в датах. - PullRequest
1 голос
/ 27 июня 2019

Мне нужно рассчитать среднее количество дней, если для каждого идентификатора имеется две или более дат: дни между датами 1 и 2, датами 2 и 3 и т. Д. Выходными данными должно быть среднее число дней между каждым интервалом для каждого идентификатора.,Я ищу решение, которое перебирает каждую дату для каждого идентификатора, а затем усредняет количество дней

. Я мог бы создать номер строки и разделить по идентификатору, но в реальных данных может быть до 20 строк.для каждого ID.

CREATE TABLE #ATABLE(
ID   INTEGER  NOT NULL  
,DATE DATE  NOT NULL
);
INSERT INTO #ATABLE(ID,DATE) VALUES (1,'1/1/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (2,'1/1/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (2,'1/10/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (2,'1/20/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (2,'1/30/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (3,'1/1/2019');
INSERT INTO #ATABLE(ID,DATE) VALUES (3,'1/10/2019');

--get avg days between orders

DROP TABLE #ATABLE

Выход для вышеупомянутого будет:

ID  AvgDatediff
1   Null
2   10
3   9

Ответы [ 3 ]

1 голос
/ 27 июня 2019

Вы можете использовать lag, чтобы получить предыдущую строку (для каждой строки), а затем найти разницу между ней и текущей строкой.Затем вы можете усреднить их:

SELECT   id, AVG(diff)
FROM     (SELECT id,
                 DATEDIFF(DAY, date, LAG(date) OVER (PARTITION BY id 
                                                     ORDER BY date DESC)) AS diff
          FROM #atable) t
GROUP BY id;
0 голосов
/ 28 июня 2019
SELECT id, AVG(DayDiff)
FROM (
    SELECT id,
    DATEDIFF(dd, date, LEAD(date) OVER (PARTITION BY id ORDER BY date)) AS DayDiff
    FROM #atable
) as AA
GROUP BY id;

LEAD(source_column) ==> выбирает следующие данные на основе заказа по предложению, т.е. здесь даты.

0 голосов
/ 27 июня 2019

Самый простой способ получить среднюю разницу:

SELECT id, DATEDIFF(DAY, MIN(date), MAX(date)) / NULLIF(COUNT(*) - 1, 0)
FROM  #atable) t
GROUP BY id;

Примечание: вы можете захотеть * 1.0, если не хотите целочисленного среднего.

Другими словамисредняя разница - самая поздняя дата минус самая ранняя дата, деленная на единицу меньше, чем число.Попытайся.Это работает.

...