【问题标题】:Dynamic Cross Apply Values动态交叉应用值
【发布时间】:2020-12-12 23:10:56
【问题描述】:

我有一些看起来像这样的代码:

SELECT  colname, SUM(value) AS items_sum, COUNT(value) AS items_count
FROM MyTable
CROSS APPLY (
    VALUES ('Item1',Item1),('Item2',Item2)
    ) x(colname, value)
WHERE Date BETWEEN @sdate AND @edate
    AND value IS NOT NULL
GROUP BY colname

我被要求将查询更改为不再对 Item1、Item2 进行硬编码,而是接受传入的任何 Item#。我尝试了一些解决方案来通过 select 语句获取 Item#,但似乎聚合函数 SUM() 和 COUNT() 抱怨,因为我尝试过的解决方案返回列名的 varchar,而不是列数据本身。有没有办法在不使用字符串连接的情况下传递列 Item#?

谢谢!

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    我已经在这个网站上发帖几个月了。我不会经常学习一些我以前没有见过的语法。

    真正酷的东西!

    我通常将代码放在测试环境中。在这种情况下,我使用了 Adventure Works 2012。

    工具提示或图片说明一千个单词。

    值列表中有元组。但是,TotalDue 不是字符串,它是指外部表 [Sales].[SalesOrderHeader]。

    SELECT 替换内部交叉应用只会带回应用于每一行的值。对外部表的引用丢失。

    鉴于这一事实,您将需要动态创建 SQL。您可以使用列名称作为 sysname 创建和填充表。然后动态编写代码,用 sp_executesql 执行。

    确保这是一个内部报告查询。 您不想引入 SQL 注入。

    此外,虽然开始并有效,但它确实不是最快或最好的方法。 日期文字是提高速度和准确性的方法。

    【讨论】:

    • 谢谢!帮助我真正理解了这个问题。最终完全按照您的建议进行。列名的 DynSQL。
    • 非常感谢您。这是 CROSS APPLY 和 GROUP BY 的一个非常有趣的用法。我真的很喜欢如何在 CROSS APPLY 中指定多个元组值(可能使用不同的列),并且结果集将包含每个元组值的 1 行聚合数据。井井有条! SELECT colname, SUM(value) as items_sum, COUNT(value) as items_count FROM Sales.SalesOrderHeader CROSS APPLY ( VALUES ('TotalDue',TotalDue), ('SubTotal',SubTotal) ) T(colname,value) WHERE value is not null GROUP BY colname
    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多