【问题标题】:SQL PIVOT on Date Range日期范围内的 SQL PIVOT
【发布时间】:2021-08-16 06:34:50
【问题描述】:

我正在尝试转换此日期列表以用作列标题。示例查询已针对 12 个日历月进行了简化注意:实际日期范围最终将总共为 240 个月。我对 PIVOT 功能不太了解

DROP TABLE if exists #nbrs
DROP TABLE if exists #nbr

DECLARE @StartDate DATE = '20210101'
DECLARE @EndDate DATE = '20211201'

SELECT  DATEADD(MONTH, nbr - 1, @StartDate) AS DateRange
    FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
          FROM      sys.columns c
        ) nbrs 
WHERE   nbr - 1 <= DATEDIFF(MONTH, @StartDate, @EndDate) 

当前输出:

DateRange
2021-01-01
2021-02-01
2021-03-01
2021-04-01
2021-05-01
2021-06-01
2021-07-01
2021-08-01
2021-09-01
2021-10-01
2021-11-01
2021-12-01

期望的输出:

2021-01-01 2021-02-01 2021-03-01

【问题讨论】:

  • 只有动态sql
  • 谢谢@KenWhite,这里比较新。感谢指导。

标签: sql sql-server date tsql pivot


【解决方案1】:

您可以通过使用动态 sql 查询和数据透视函数来实现所需的输出。除了日期列之外,我还为枢轴函数添加了另一个虚拟列。

DECLARE @StartDate DATE = '20210101';
DECLARE @EndDate DATE = '20211201';
DECLARE @DynamicQuery AS NVARCHAR(MAX);
DECLARE @ColumnList AS NVARCHAR(MAX);

-- populate column list 
WITH DateRange(DateData) AS 
(
    SELECT @StartDate as Date
    UNION ALL
    SELECT DATEADD(MONTH,1,DateData)
    FROM DateRange 
    WHERE DateData < @EndDate
)
SELECT @ColumnList = ISNULL(@ColumnList + ',', '')
        + QUOTENAME(DateData)
FROM DateRange
OPTION (MAXRECURSION 300);

-- Construct dynamic query
SELECT @DynamicQuery = N' WITH DateRange(DateData, AnotherColumn) AS 
      (
          SELECT CAST(''' + CAST(@StartDate AS NVARCHAR) + ''' as Date) as DateData, 1 as AnotherColumn
          UNION ALL
          SELECT DATEADD(MONTH,1,DateData), 1 as AnotherColumn
          FROM DateRange 
          WHERE DateData <  ''' + CAST(@EndDate  AS NVARCHAR) + '''
      )
      SELECT ' + @ColumnList + ' FROM (
      SELECT * FROM DateRange
    ) As SouceTable PIVOT (MAX(AnotherColumn) FOR DateData IN ( ' +
    @ColumnList + ')) AS PivotTable
    OPTION (MAXRECURSION 300)';

-- run @DynamicQuery;
EXEC sp_executesql @DynamicQuery;

结果:

【讨论】:

  • 谢谢@Yared。但是,当我将开始和结束扩展到 10 年跨度时,我收到一个递归错误:消息 530,级别 16,状态 1,第 7 行语句终止。在语句完成之前,最大递归 100 已用完。我的特定用途的目标是启用 240 个月(10 年)的动态日期范围
  • 发生这种情况是因为 CTE(通用表表达式)的递归级别超过了默认限制(即 100)。通过使用 MAXRECURSION 选项增加阈值可以轻松解决此问题。我已更新查询以适应此更改。
猜你喜欢
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多