不同的聚合函数取决于数据类型
Posted
技术标签:
【中文标题】不同的聚合函数取决于数据类型【英文标题】:Different aggregate functions depending on datatype 【发布时间】:2018-01-06 20:26:27 【问题描述】:我有一个 T-SQL 脚本,它返回表中的所有列,以及从 sys.columns
和 sys.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
【讨论】:
以上是关于不同的聚合函数取决于数据类型的主要内容,如果未能解决你的问题,请参考以下文章