0

Я постараюсь сделать это так просто, как я могу:Поворотная таблицу с результатами diveded по USERNAME

У меня есть таблица, которая регистрирует все, что пользователь (сотрудник) делает (может начать свою работу, регистрации новых продуктов, доставки продуктов и прекращения его работы). Самый распространенный сценарий - это когда пользователь начинает свою работу, делает все, что ему нужно делать в течение дня, а затем заканчивает свою работу в тот же день, когда он начал, так что теперь это информация, которая важна для меня сейчас (начало и конец).

Этот запрос:

SELECT DISTINCT 
DATEPART(DAY,TimeStamp) [Day], 
DATEPART(MONTH,TimeStamp) [Month], 
DATEPART(YEAR,TimeStamp) [Year], 
login [USER], 
CASE WHEN TipoOcorrencia = 'IniciarDia'  THEN 'YES' END [Started], 
CASE WHEN TipoOcorrencia = 'FinalizacaoDia' THEN 'YES' END [Ended] 
FROM CHAMADO ch 
WHERE 
    TimeStamp >= '20151001' 
    AND TipoOcorrencia = 'IniciarDia' OR TipoOcorrencia = 'FinalizacaoDia' 
GROUP BY 
    DATEPART(DAY,TimeStamp), 
    DATEPART(MONTH,TimeStamp), 
    DATEPART(YEAR,TimeStamp), 
    login, 
    TipoOcorrencia 
ORDER BY [USER], [Year],[Month],[Day] 

возвращает что-то вроде этого (но с большим количеством пользователей):

results without pivot

Вы можете видеть, что этот пользователь начал и закончил свой день работы на том же даты в три разных дня (10/7, 10/8 и 10/9).

Правильно используя PIVOT Я считаю, что можно получить следующий ожидаемый результат: expected result with pivot

Очевидно, что моя проблема в том, что я, несмотря на попытки очень трудно, не могли сделать PIVOT работы. И мне нужна помощь ...

Заранее спасибо!

+1

Оберните свои заявления о делах max и избавьтесь от группы на tipocorrencia – xQbert

ответ

1

Не положительный, но я считаю, что это будет работать:

SELECT DISTINCT 
DATEPART(DAY,TimeStamp) [Day], 
DATEPART(MONTH,TimeStamp) [Month], 
DATEPART(YEAR,TimeStamp) [Year], 
login [USER], 
--Modified these two lines 
max(CASE WHEN TipoOcorrencia = 'IniciarDia'  THEN 'YES' END) [Started], 
max(CASE WHEN TipoOcorrencia = 'FinalizacaoDia' THEN 'YES' END) [Ended] 
--End modification 
FROM CHAMADO ch 
WHERE 
    TimeStamp >= '20151001' 
    AND TipoOcorrencia = 'IniciarDia' OR TipoOcorrencia = 'FinalizacaoDia' 
GROUP BY 
    DATEPART(DAY,TimeStamp), 
    DATEPART(MONTH,TimeStamp), 
    DATEPART(YEAR,TimeStamp), 
    login--, 
    --commented out this next one and remove comma above. 
    --TipoOcorrencia 
ORDER BY [USER], [Year],[Month],[Day] 

Почему это работает? tipoOcorrencia группируется, и вам нужно было из-за вашего оператора case, но если вы максимизируете значение, вы можете исключить группу, вызвав объединение нескольких строк.

Альтернативный подход заключается в том, чтобы рассматривать это как таблицу и получать максимальные значения после факта ... но это медленнее и менее чисто, по моему мнению, поскольку оно решает симптом, а не проблему.

with cte as (SELECT DISTINCT 
DATEPART(DAY,TimeStamp) [Day], 
DATEPART(MONTH,TimeStamp) [Month], 
DATEPART(YEAR,TimeStamp) [Year], 
login [USER], 
CASE WHEN TipoOcorrencia = 'IniciarDia'  THEN 'YES' END [Started], 
CASE WHEN TipoOcorrencia = 'FinalizacaoDia' THEN 'YES' END [Ended] 
FROM CHAMADO ch 
WHERE 
    TimeStamp >= '20151001' 
    AND TipoOcorrencia = 'IniciarDia' OR TipoOcorrencia = 'FinalizacaoDia' 
GROUP BY 
    DATEPART(DAY,TimeStamp), 
    DATEPART(MONTH,TimeStamp), 
    DATEPART(YEAR,TimeStamp), 
    login, 
    TipoOcorrencia) 

Select 
[Day],[Month],[Year], 
login , Max([Started]), max([Ended]) 
from cte 
GROUP BY [Day],[Month],[Year], 
login 
ORDER BY [USER], [Year],[Month],[Day] 
+0

Ваш первый подход решил проблему. Второй возвращенный 'Msg 1033, Level 15, State 1, Line 43 Предложение ORDER BY недопустимо в представлениях, встроенных функциях, производных таблицах, подзапросах и общих табличных выражениях, если не указано значение TOP, OFFSET или FOR XML.' –

+0

ah пришлось переместить заказ на запрос на cte. – xQbert

+0

сожалею о моей глупости, но я до сих пор не могу понять, почему это работает, и как сгруппировано tipoOcorrencia, вызывая половину проблемы. Не могли бы вы снова попытаться объяснить это мне? Tks! –

1

Один из способов, с помощью которого можно было бы работать, - немного изменить свои операторы CASE. Кроме того, пожалуйста, измените предоставленные данные, чтобы показать, что вы ожидаете увидеть, если кто-то не начнет и не закончит свою работу в тот же день.

SELECT DISTINCT 
DATEPART(DAY,TimeStamp) [Day], 
DATEPART(MONTH,TimeStamp) [Month], 
DATEPART(YEAR,TimeStamp) [Year], 
login [USER], 
MAX(CASE WHEN TipoOcorrencia = 'IniciarDia' THEN 1 ELSE 0 END) AS [Started], 
MAX(CASE WHEN TipoOcorrencia = 'FinalizacaoDia' THEN 1 ELSE 0 END) AS [Ended] 
FROM CHAMADO ch 
WHERE 
    TimeStamp >= '20151001' 
    AND TipoOcorrencia = 'IniciarDia' OR TipoOcorrencia = 'FinalizacaoDia' 
GROUP BY 
DATEPART(DAY,TimeStamp), 
DATEPART(MONTH,TimeStamp), 
DATEPART(YEAR,TimeStamp), 
login 
ORDER BY [USER], [Year],[Month],[Day] 

Также, как примечание стороны, это лучшая практика кодирования SQL, чтобы включить оператор ELSE в коде CASE.

+0

IDK, но почему сервер sql возвращает 'Msg 102, Level 15, State 1, Line 29 Некорректный синтаксис около ','.' –

+0

Отсутствует конец) для каждой из максимальных агрегатов после END каждого случая , 'MAX (CASE WHEN TipoOcorrencia = 'IniciarDia' THEN 1 ELSE 0 END ^^^) ^^^ AS [Started],' – xQbert

Смежные вопросы