You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server同时透视含datetime列的两列的实现问题

解决方案

你遇到的问题根源是:源表中加入DeviceFirstScannedTime后,该列的不同值会打破原有的分组逻辑——SQL Server会把同一人员但扫描时间不同的行视为独立分组,最终导致透视结果拆分成多行。要实现同时透视计数和日期时间列并保持单行展示,有两种高效的实现方式:

方式一:条件聚合(推荐,SQL Server 2012完全支持)

先对源数据按人员+日期做聚合,确保同一人员每天只有一条记录(包含当天的扫描时间和考勤计数),再用条件聚合生成目标列:

SELECT
  Firstname,
  Company,
  -- 提取2023-02-06的扫描时间
  MAX(CASE WHEN DeviceScannedDateOnly = '2023-02-06' THEN DeviceFirstScannedTime END) AS [06 Scanned time],
  -- 统计2023-02-06的考勤次数
  SUM(CASE WHEN DeviceScannedDateOnly = '2023-02-06' THEN 1 ELSE 0 END) AS [06/02/23],
  -- 提取2023-02-07的扫描时间
  MAX(CASE WHEN DeviceScannedDateOnly = '2023-02-07' THEN DeviceFirstScannedTime END) AS [07 Scanned Time],
  -- 统计2023-02-07的考勤次数
  SUM(CASE WHEN DeviceScannedDateOnly = '2023-02-07' THEN 1 ELSE 0 END) AS [07/02/23]
FROM (
  -- 先聚合:按人员、公司、日期分组,取当天最早的扫描时间
  SELECT
    Firstname,
    CompanyName AS Company,
    DeviceScannedDateOnly,
    MIN(DeviceFirstScannedTime) AS DeviceFirstScannedTime
  FROM [dbo].[vLDN23_DailyReportForPivot]
  GROUP BY Firstname, CompanyName, DeviceScannedDateOnly
) AS AggregatedData
GROUP BY Firstname, Company;

方式二:结合UNPIVOT与PIVOT(适合多列透视场景)

如果需要透视的列较多,可以先将计数和时间列拆分成键值对,再统一透视:

SELECT
  Firstname,
  Company,
  [06/02/2023_Count] AS [06/02/23],
  [06/02/2023_Time] AS [06 Scanned time],
  [07/02/2023_Count] AS [07/02/23],
  [07/02/2023_Time] AS [07 Scanned Time]
FROM (
  SELECT
    Firstname,
    CompanyName AS Company,
    -- 拼接日期和类型,生成透视的列标识
    CONVERT(VARCHAR(10), DeviceScannedDateOnly, 103) + '_Count' AS PivotColumn,
    CAST(COUNT(Code) AS VARCHAR(10)) AS PivotValue
  FROM [dbo].[vLDN23_DailyReportForPivot]
  GROUP BY Firstname, CompanyName, DeviceScannedDateOnly
  UNION ALL
  SELECT
    Firstname,
    CompanyName AS Company,
    CONVERT(VARCHAR(10), DeviceScannedDateOnly, 103) + '_Time' AS PivotColumn,
    CONVERT(VARCHAR(23), MIN(DeviceFirstScannedTime), 121) AS PivotValue
  FROM [dbo].[vLDN23_DailyReportForPivot]
  GROUP BY Firstname, CompanyName, DeviceScannedDateOnly
) AS SourceTable
PIVOT (
  MAX(PivotValue)
  FOR PivotColumn IN ([06/02/2023_Count], [06/02/2023_Time], [07/02/2023_Count], [07/02/2023_Time])
) AS PivotTable;

关键说明

  • 两种方式都先对源数据做了预聚合:通过GROUP BY Firstname, CompanyName, DeviceScannedDateOnly确保同一人员每天只有一条记录,避免因DeviceFirstScannedTime的细微差异导致分组拆分。
  • 条件聚合写法更简洁直观,适合固定日期的报表场景;UNPIVOT+PIVOT更灵活,适合需要动态生成透视列的场景(可结合动态SQL实现)。

内容的提问来源于stack exchange,提问作者Michael Gouveia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:13:59