Функция SQL Server LAG() для вычисления различий между строками

Я новичок в SQL Server, и у меня есть некоторые сомнения по поводу функции lag(). Мне нужно рассчитать среднее расстояние (в днях) между действиями двух пользователей. Затем я должен ГРУППИРОВАТЬ по всем пользователям, вычислить все различия дат между строками для каждого пользователя и, наконец, выбрать среднее значение группы.

Просто для ясности, у меня есть такая таблица: original table


Сначала я должен отфильтровать дни с действиями (деятельности! = 0). Затем я должен создать это:

вычислить разницу между строками

И, наконец, ожидаемый результат таков:

что я хочу

Я думал, что это может быть "своего рода" код:

select userid, avg(diff)
  (SELECT *,DATEDIFF(day, Lag(dateid, 1) OVER(ORDER BY [Userid]), 
   dateid) as diff
   FROM table1
   where activities!=0
   group by userid) t
group by userid

Конечно, это не работает. Я думаю, что мне также нужно выполнить цикл while, поскольку номер строки изменяется для каждого пользователя.

Я надеюсь, что вы можете помочь мне! большое тебе спасибо


person Community    schedule 07.09.2018    source источник
comment
Добро пожаловать в Stackoverflow. Вместо того, чтобы публиковать данные в виде изображений, многие добровольцы здесь предпочли бы, чтобы вы предоставили их как text. Если вы хотите быть действительно полезным, операторы DDL и INSERT еще лучше (Как опубликовать Вопрос T-SQL). Некоторые данные на вашем изображении выглядят так, как будто они отсутствуют (например, где значение для действий в 3-й строке на первом изображении). Я также не вижу, как данные из первого изображения становятся данными во втором. Если вы предоставите операторы DDL и INSERT, это будет очень полезно.   -  person Larnu    schedule 07.09.2018


Ответы (2)


Вы почти там. Просто добавьте partition by userid, чтобы вычислялась разница для каждого идентификатора пользователя и order by dateid.

select userid, avg(diff)
  (SELECT t.*
         ,DATEDIFF(day, Lag(dateid, 1) OVER(PARTITION BY [Userid] ORDER BY [dateid]),dateid) as diff
   FROM table1 t
   where wager!=0
  ) t
group by userid
person Vamsi Prabhala    schedule 07.09.2018
comment
Спасибо Вамси! На данный момент я не вижу, работает ли это, но я дам вам знать! - person ; 07.09.2018

Вам вообще не нужно lag(). Среднее значение равно максимуму минус минимум, деленному на единицу меньше числа:

SELECT userid,
       DATEDIFF(day, MIN(dateid), MAX(dateid)) * 1.0 / NULLIF(COUNT(*), 1) as avg_diff
FROM table1
WHERE wager<> 0
GROUP BY userid;
person Gordon Linoff    schedule 07.09.2018