Sql server 使用按用户名分隔的结果透视表
我会尽可能地简单: 我有一个表,可以记录用户(员工)正在做的任何事情(可以是开始工作、注册新产品、交付产品和结束工作)。最常见的情况是当用户开始他的工作,在一天中做他需要做的任何事情,然后在他开始的同一天结束他的工作,所以这些信息现在对我很重要(开始和结束) 此查询:Sql server 使用按用户名分隔的结果透视表,sql-server,sql-server-2008,tsql,sql-server-2005,sql-server-2012,Sql Server,Sql Server 2008,Tsql,Sql Server 2005,Sql Server 2012,我会尽可能地简单: 我有一个表,可以记录用户(员工)正在做的任何事情(可以是开始工作、注册新产品、交付产品和结束工作)。最常见的情况是当用户开始他的工作,在一天中做他需要做的任何事情,然后在他开始的同一天结束他的工作,所以这些信息现在对我很重要(开始和结束) 此查询: SELECT DISTINCT DATEPART(DAY,TimeStamp) [Day], DATEPART(MONTH,TimeStamp) [Month], DATEPART(YEAR,TimeStamp) [Year],
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]
返回如下内容(但用户数更多):
您可以看到,该用户在三个不同的日期(10/7、10/8和10/9)的同一天开始和结束了他的工作日
通过正确使用轴,我相信可以获得以下预期结果:
显然,我的问题是,尽管我真的很努力,但还是无法使轴工作。我需要帮助
提前谢谢 不是积极的,但我相信这会奏效:
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]
一种可能有效的方法是稍微修改您的案例陈述。此外,请修改您提供的数据,以显示如果有人没有在同一天开始和结束工作,您将看到什么
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语句 将您的案例语句包装在max中,并在tipocorrenciaIDK上删除group by。为什么sql server在每个案例结束后返回每个max聚合的
Msg 102,级别15,状态1,第29行“,”附近的语法不正确。
It's missing end)<代码>最大值(当TIPOOCORRECIA='IniciarDia'然后1个其他0 END^^^^^^^^^作为[开始],您的第一种方法解决了问题。第二个返回的Msg 1033,级别15,状态1,第43行ORDER BY子句在视图、内联函数、派生表、子查询和公共表表达式中无效,除非还指定了TOP、OFFSET或FOR XML。
ah必须将ORDER BY移动到cte上的查询。对不起,我的愚蠢,但我仍然无法完全理解它为什么会起作用,以及tipoOcorrencia是如何被分组的,导致了一半的问题。你能再给我解释一下吗?Tks!分组依据没有分组是,否。。。它是根据IniciarDia Finalizaacodia和TIpoOcorrencia的所有其他值进行分组的。正是这些其他值导致了其他记录的出现。通过使用max语句,我们排除了所有其他值,因为我们消除了group By。获取原始查询并将tipo)Correncia添加到select。您可能会更好地理解为什么显示它。另一种选择是使用where子句来限制case语句中的两个值。或者添加一个