首页 > 解决方案 > 在 SELECT 查询 SQL 中生成动态日期列

问题描述

首先我有一个这样的表:

虚拟身份证 投标 日期 类型 价值
1 100 22.01.2021 250.00
1 110 25.01.2021 C 100.00
2 120 13.02.2021 400.00
3 130 20.02.2021 475.00
3 140 2022 年 3 月 11 日 C 75.00
1 150 2022 年 3 月 15 日 560.00

为了显示每月订购(o)和收费(c)的值,我必须喜欢在 MSSQL SELECT 查询中为每个月订购和收费的“生成”列。这是我想要获得的示例表:

虚拟身份证 JAN2021O JAN2021C FEB2021O FEB2021C …</th> MAR2022O MAR2022C
1 250.00 100.00 560.00
2 400.00
3 475.00 75.00

除了我已经拥有的其他一些列之外,我还需要将它加入到 SQL SELECT 中。

有人有想法可以帮助我吗?

标签: sqlsql-serverjoin

解决方案


SQL 语言有一个非常严格的要求,即在查询编译时,在查看表中的任何数据之前,要知道结果中的列数和每列的类型。这甚至适用于和查询,其中列仍然在查询编译时通过表定义(而不是数据)或 SQL 语句确定。SELECT *PIVOT

因此,如果您想显示从基准日期算起的特定、已知的月数,您想要执行的操作只能在单个查询中完成。在这种情况下,您可以通过在 SQL 中指定每一列并使用带有条件聚合的日期数学来计算从起点开始的每个月的值来完成此操作。关键字可以帮助减少代码,PIVOT但是您仍然要手动指定每一列,并且查询仍然远非微不足道。

如果您没有特定的、已知的要评估的月数,则必须通过以下几个步骤执行此操作:

  1. 运行查询以了解您有多少个月。
  2. 使用第 1 步的结果动态构造新语句
  3. 运行在步骤 2 中构建的语句。

没有其他办法。

即便如此,这种枢轴通常在客户端代码或报告工具(在表示级别)中比通过 SQL 本身更好地处理。

这个特定查询不太可能出现,但您还应该知道,这种动态 SQL 可能会引发某些安全问题,因为一些防止注入问题的正常机制不可用(在步骤 2 中构建新查询时,您无法参数化源列的名称,这些名称取决于可能是用户生成的数据。


推荐阅读