【问题标题】:Pivot all Time Data on Date Column透视日期列上的所有时间数据
【发布时间】:2020-01-17 00:12:34
【问题描述】:

我需要在 SQL Server 报告服务中创建一个报告。源表/查询数据的结构如下:

 CNum |  EmpNo   |    TDate      | TimeIn    |  TimeOut 
  100 |  2       |   12/4/2019   |  7:00 AM  |  12:00 PM
  100 |  2       |   12/4/2019   |  12:30 PM |  3:30 PM
  100 |  2       |   12/5/2019   |  7:00 AM  |  12:00 PM
  100 |  2       |   12/5/2019   |  12:30 PM |  3:30 PM 

我需要将报告输出显示如下(或类似的内容,只需将 TDate 显示为列,并将任何基于 CNum 的相关时间条目显示为行)。

 CNum |  12/4/2019 |   12/5/2019 | 
  100 |  7:00 AM   |   7:00 AM   | 
      |  12:00 PM  |   12:00 PM  |  
  100 |  12:30 PM  |   12:30 PM  | 
      |  3:30 PM   |   3:30 PM   | 

我曾尝试使用 Matrix Tablix,但这会强制该组每天仅返回记录,而可能有多个。我的目标是编写一个 SQL 查询(CTE 或 PIVOT),它将以正确的格式为我提供报告数据,这样我就不必在报告设计器中发疯了。

我熟悉 SQL,但由于某种原因,我无法将任何查询输出 (Pivot) 并包含当天的两条记录。

任何帮助/指导将不胜感激。

【问题讨论】:

    标签: sql sql-server ssrs-2008 pivot-table report-designer


    【解决方案1】:

    您可以在 SSRS 中轻松完成此操作,只需对数据集查询稍作更改。

    我用以下内容复制了您的示例数据

    DECLARE @t TABLE(CNum int, EMpNo int, TDate Date, TimeIn Time, [Timeout] Time)
    INSERT INTO @t VALUES
    (100, 2, '2019/12/04', '07:00', '12:00'),
    (100, 2, '2019/12/04', '12:30', '15:30'),
    (100, 2, '2019/12/05', '07:00', '12:00'),
    (100, 2, '2019/12/05', '12:30', '15:30')
    
    
    SELECT *, ROW_NUMBER() OVER(PARTITION BY TDate, Cnum ORDER BY TimeIn) as RowN FROM @t 
    

    注意:我添加了 RowN 列,它在每个 TDateCNum 中为每一行提供一个唯一编号。我们将它添加到矩阵中的 CNum 组(因此它按 CNum 然后 RowN 分组)

    这是包含行组和列组的最终设计(列组仅按 TDate)

    为了获得第二行,我右键单击 [TimeIn] 'cell' 并执行“插入行 = > 内部组 - 下方”

    最终的输出是这样的

    【讨论】:

    • 绝对是我需要的!!!!太感谢了。 RowN 是关键。
    【解决方案2】:

    我想,你可以从Efficiently convert rows to columns in sql server 转发过来

    【讨论】:

      【解决方案3】:

      这是答案:

      With CTE as (
          Select
              CNum,
              TDate,
              TimeIn as [Time],
              'In' as [Action]
          From TimeTable
          Union All
          Select
              CNum,
              TDate,
              [TimeOut] as [Time],
              'Out' as [Action]
          From TimeTable
      )
      Select
          *
      From CTE
      Pivot(min([Time]) for TDate in ([2019-12-04],[2019-12-05])) as pivot_table
      union all
      Select
          *
      From CTE
      Pivot(max([Time]) for TDate in ([2019-12-04],[2019-12-05])) as pivot_table
      

      【讨论】:

      • 这看起来可行,但是表和 TDate 字段中的数据是动态的(一直在增长)。如上所示,我无法对“IN”子句进行硬编码。有没有一种方法可以动态执行以下操作:Pivot(min([Time]) for TDate in ([2019-12-04],[2019-12-05]))
      • 在数据库视图中无法生成动态数据(每次运行不同的列名)。因此您可以将其更改为存储过程。
      猜你喜欢
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      相关资源
      最近更新 更多