在 SELECT 查询 SQL 中生成动态日期列
Posted
技术标签:
【中文标题】在 SELECT 查询 SQL 中生成动态日期列【英文标题】:Generate dynamic date columns in a SELECT query SQL 【发布时间】:2021-12-11 23:10:59 【问题描述】:首先我有一张这样的表:
vID | bID | date | type | value |
---|---|---|---|---|
1 | 100 | 22.01.2021 | o | 250.00 |
1 | 110 | 25.01.2021 | c | 100.00 |
2 | 120 | 13.02.2021 | o | 400.00 |
3 | 130 | 20.02.2021 | o | 475.00 |
3 | 140 | 11.03.2022 | c | 75.00 |
1 | 150 | 15.03.2022 | o | 560.00 |
为了显示每月订购(o)和收费(c)的值,我必须喜欢在 MSSQL SELECT 查询中为每个月订购和收费的“生成”列。 这是我想要得到的示例表:
vID | JAN2021O | JAN2021C | FEB2021O | FEB2021C | … | MAR2022O | MAR2022C |
---|---|---|---|---|---|---|---|
1 | 250.00 | 100.00 | 560.00 | ||||
2 | 400.00 | ||||||
3 | 475.00 | 75.00 |
除了我已经拥有的其他一些列之外,我还需要将它加入到 SQL SELECT 中。
有没有人有想法可以帮助我?
【问题讨论】:
老实说,我真的推荐这个想法。如果您“必须”旋转您的数据(动态),请在您的演示/报告层中进行。在 T-SQL 中执行此操作将需要动态 SQL,除非您精通该语言,否则不应该使用动态 SQL。 【参考方案1】:SQL 语言有一个非常严格的要求要知道结果中的列数和每列的类型 在查询编译时,在查看表中的任何数据之前。这甚至适用于 SELECT *
和 PIVOT
查询,其中列仍然在查询编译时通过表定义(而不是数据)或 SQL 语句确定。
因此,如果您想显示从基准日期算起的特定的已知月数,您只能在单个查询中执行此操作。在这种情况下,您可以通过在 SQL 中指定每一列并使用带有条件聚合的日期数学来计算从您的起点开始的每个月的值来完成此操作。 PIVOT
关键字可以帮助减少代码,但您仍然要手动指定每一列,查询仍然远非微不足道。
如果您没有具体的、已知的要评估的月数,则必须分几个步骤进行:
-
运行查询以了解您有多少个月。
使用第 1 步的结果动态构造新语句
运行步骤 2 中构造的语句。
没有别的办法。
即便如此,这种数据透视通常在客户端代码或报告工具(在表示级别)中比通过 SQL 本身更好地处理。
这种特定查询不太可能出现,但您还应该注意,这种动态 SQL 可能会引发某些安全问题,因为一些防止注入问题的正常机制不是在步骤 2 中构建新查询时可用(您无法参数化源列的名称,这些名称取决于可能是用户生成的数据)。
【讨论】:
以上是关于在 SELECT 查询 SQL 中生成动态日期列的主要内容,如果未能解决你的问题,请参考以下文章
在CTE中使用最大递归来生成CTE,而不是仅在最终的SELECT语句中生成CTE