【问题标题】:Pivoting a table with results diveded by USERNAME透视表,结果除以 USERNAME
【发布时间】:2016-02-28 15:41:50
【问题描述】:

我会尽量简化:

我有一个表格,可以记录用户(员工)正在做什么(可以是开始他的工作、注册新产品、交付产品和结束他的工作)。最常见的情况是当用户开始他的工作,在白天做他需要做的任何事情,然后在他开始的同一天结束他的工作,所以这些是现在对我很重要的信息(开始和结束)。

这个查询:

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 日)的同一日期开始和结束了他的工作日。

通过正确使用PIVOT,我相信可以得到如下预期结果:

显然我的问题是,尽管我非常努力,但仍无法使 PIVOT 工作。我需要帮助...

提前致谢!

【问题讨论】:

  • 将您的案例陈述包装在 max 中,并在 Tipocorrencia 上摆脱 group by

标签: sql-server sql-server-2008 tsql sql-server-2005 sql-server-2012


【解决方案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 被分组,你需要因为你的案例陈述,但如果你最大化值,你可以通过合并多行来消除组。

另一种方法是将其视为表格本身,并在事后获取最大值...但在我看来,这会更慢且不太干净,因为它解决了症状,而不是问题。

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]

【讨论】:

  • 您的第一种方法解决了问题。第二个返回Msg 1033, Level 15, State 1, Line 43 The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
  • 啊必须将订单移至 cte 上的查询。
  • 对不起,我的愚蠢,但我仍然无法完全理解它为什么起作用,以及如何将tipoOcorrencia 分组导致问题的一半。你愿意再向我解释一下吗?谢了!
  • 分组依据不是分组是,否...它分组的是 IniciarDia FinalizacaoDia 和 TIpoOcorrencia 的所有其他值。正是这些其他值导致出现其他记录。通过使用 max 语句,我们排除了所有其他值,因为我们消除了 group by。获取您的原始查询并将tipo)Correncia 添加到选择中。您可能能够理解为什么显示它会更好。另一种选择是使用 where 子句来限制 case 语句中的两个值。或添加一个拥有
【解决方案2】:

这可能起作用的一种方法是稍微更改您的 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 编码的最佳做法是在 CASE 代码中包含 ELSE 语句。

【讨论】:

  • IDK 为什么 sql server 返回 Msg 102, Level 15, State 1, Line 29 Incorrect syntax near ','.
  • 每个案例结束后的每个最大聚合都缺少 end )。 MAX(CASE WHEN TipoOcorrencia = 'IniciarDia' THEN 1 ELSE 0 END^^^)^^^AS [Started],
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多