SQL Server - агрегируйте количество ошибок на пользователя в день - PullRequest
0 голосов
/ 26 октября 2018

Приложение, которое я поддерживаю, хранит пользовательские ошибки в таблице SQL Server.Когда возникает ошибка, она записывает имя пользователя, вызвавшего ее, время, сообщение об ошибке и некоторые другие служебные действия.

Я пытаюсь создать отчет, в котором мы могли бы увидеть "топ-3 "ошибки каждый день в течение прошлого года - три пользователя с наибольшим количеством ошибок в каждый день, три наиболее распространенных типа ошибок в каждый день и т. д.

Моя цель примерно такая:

DATE       USER1    ERR_COUNT1    USER2    ERR_COUNT2    USER3    ERR_COUNT3
1/1/18     BOB      70            BILL     50            JOE      30
1/2/18     JILL     55            JOY      30            BOB      20
... 

У меня настроен грубый цикл для извлечения этих данных из наших журналов ошибок, но когда я их запускаю, я получаю ошибку There is already an object named '#TempErrorLog'in the database.Код цикла ниже:

DECLARE @StartDate AS DATE,
        @EndDate AS DATE

SET @StartDate = '2018.1.1'

WHILE @StartDate <= CONVERT(DATE, GETDATE())
    BEGIN
        SET @EndDate = DATEADD(DAY, 1,  @StartDate) 

        SELECT @StartDate AS date_err,
               ( u.name_frst+' '+u.name_lst ) AS user_err,
               COUNT(e.id_err) AS count_err
        INTO dbo.#TempErrLog
        FROM err_log AS e
             LEFT JOIN users AS u ON e.id_user = u.id_user
        WHERE e.dttm_err >= @StartDate AND
              e.dttm_err < @EndDate AND
              e.id_user <> 'system'
        GROUP BY ( u.name_frst+' '+u.name_lst )
        ORDER BY count_err DESC;

        SET @StartDate = DATEADD(DAY, 1,  @StartDate)

            CONTINUE
    END

SELECT * FROM #TempErrLog

Я предполагаю, что он пытается создать новую временную таблицу каждый раз, когда цикл повторяется.Есть ли лучший подход, который я должен использовать здесь?

1 Ответ

0 голосов
/ 26 октября 2018

Вы можете повернуть это с помощью условного агрегирования и row_number(). Для результатов в вашем вопросе:

with ue as (
      select e.*, (u.name_frst + ' ' + u.name_lst ) as user_name,
             cast(e.dttm_err as date) as err_date
      from err_log e join
           users u
           on e.id_user = u.id_user
     )
select u.err_date,
       max(case when u.seqnum = 1 then u.user_name end) as user_1,
       max(case when u.seqnum = 1 then u.cnt end) as cnt_1,
       max(case when u.seqnum = 2 then u.user_name end) as user_2,
       max(case when u.seqnum = 2 then u.cnt end) as cnt_2,
       max(case when u.seqnum = 3 then u.user_name end) as user_3,
       max(case when u.seqnum = 3 then u.cnt end) as cnt_3
from (select err_date, user_name, count(*) as cnt,
             row_number() over (partition by err_date order by count(*) desc) as seqnum
      from ul
      group by err_date, user_name
     ) u 
group by u.err_date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...