不同的聚合函数取决于数据类型

Posted

技术标签:

【中文标题】不同的聚合函数取决于数据类型【英文标题】:Different aggregate functions depending on datatype 【发布时间】:2018-01-06 20:26:27 【问题描述】:

我有一个 T-SQL 脚本,它返回表中的所有列,以及从 sys.columnssys.types 获取的数据类型和最大值 MAX(DATALENGTH))

但是对于 ints,最大值始终为 4,因为 ints 使用 4 个字节。在这种情况下,我宁愿使用列的最高数值。

我想我可能会更改我的查询以将DataLength 用于基于字符串的列,将MAX() 用于基于数字的列,但是在我到达那里之前遇到了一些问题:

缩小的示例代码

DECLARE @A bit = 1
SELECT CASE WHEN 1=1 THEN MAX(DATALENGTH(@A)) ELSE MAX(@A) END

鉴于1=1 为真,我希望收到数字 1。 相反,我得到一个错误

操作数数据类型位对 max 运算符无效。

我知道你不能运行MAX(@A),但这不是我想要做的。我的目标是根据数据类型运行不同的聚合函数。

我该如何解决这个问题?

【问题讨论】:

旁白:CASE 不能可靠地提供短路评估。请参阅CASE / COALESCE won't always evaluate in textual order、FREETEXT() does not honor order of evaluation in CASE statements 和 Aggregates Don't Follow the Semantics Of CASE。 【参考方案1】:

我的目标是根据数据类型运行不同的聚合函数。

这将失败,因为您将收到无效转换错误或将隐式转换为最高优先级数据类型

您对bit 的使用在这里无关紧要

smalldatetime has the highest precedence 所以这段代码在混合数据类型时会给出奇怪的结果

DECLARE @foo table (
 intval int,
 floatval float,
 datetimeval smalldatetime)

 INSERT @foo VALUES
 (1, 1.567E2, '2017-07-31'),
 (2, 2.0, '2017-08-01');

 DECLARE @Switch int;
 SELECT 
        CASE 
            WHEN @Switch=1 THEN MAX(intval)
            WHEN @Switch=2 THEN MAX(floatval)
            ELSE MAX(datetimeval) 
        END
FROM 
    @foo

 SET @Switch = 1
 1900-01-03 00:00:00

 SET @Switch = 2
 1900-06-06 16:48:00

 SET @Switch = 3
 2017-08-01 00:00:00

【讨论】:

什么问题?如果您选择了未知问题的解决方案,我们拥有的一切【参考方案2】:

在这种情况下,您缺少演员表:

SELECT CASE WHEN 1=1 THEN MAX(DATALENGTH(@A)) ELSE MAX(CAST(@A as bigint)) END

【讨论】:

以上是关于不同的聚合函数取决于数据类型的主要内容,如果未能解决你的问题,请参考以下文章

Dask数据框中的多个聚合用户定义函数

在sql数据库中,我用聚合函数sum,为啥显示操作数据类型varchar对于sum运算符无效啊?

C语言中,啥是聚合类型?

如何对返回类型取决于参数的输入类型的函数进行类型提示?

8.聚合函数

如何让单个接口返回不同的数据类型?