【问题标题】:Choose returns null选择返回 null
【发布时间】:2021-12-25 01:24:09
【问题描述】:
SELECT
    r.[value] as KnownRandomNumber,
    CHOOSE(r.[value], 5, 15, 16, 17) AS KnownRandomResult,
    CHOOSE(FLOOR(RAND() * 4) + 1, 5, 15, 16, 17) AS UnknownRandomResult
FROM
    (SELECT FLOOR(RAND() * 4) + 1 AS [value]) r

为什么CHOOSE(FLOOR(RAND() * 4) + 1, 5, 15, 16, 17) 有时会返回 null?即使使用从子查询中获得的随机数永远不会返回null?

我在 SQL Server Management Studio 的 Microsoft SQL Server 上运行它。

【问题讨论】:

  • CHOOSE(x, a, b, c)CASE WHEN x = 1 THEN a WHEN x = 2 THEN b WHEN x = 3 THEN c END 的简写,x 对每个 CASE 进行单独评估。如果驱动CHOOSE 的表达式是不确定的(包括RAND(),但不包括列引用),则结果可以是任何内容,包括不匹配大小写。此处的文档完全没有提及这一点是错误的,但如果您获取执行计划,它会立即可见。
  • 谢谢!有道理,这消除了混乱。
  • 实际上 - 选择是简单案例表达式的简写。这将是:CASE X WHEN 1 THEN a WHEN 2 THEN b WHEN 3 THEN c END。无论哪种方式 - 如果没有找到匹配项,则返回 NULL。
  • 我猜想将 rand 与 choose 一起使用的问题在于,选择变成:当 rand() =1 然后 {a} 当 rand()=2 然后 {b} ...并且每次检查都会生成随机数......这可能会混淆“选择”函数并使其有时返回 null ,因为该函数不是用来处理非确定性函数作为输入
  • @Jeff: ...但是一个简单的CASE 表达式本身是“完整”CASE 表达式的简写,这实际上是引擎支持的所有内容。归根结底,任何涉及CASE 的事情最终都会多次评估输入表达式,而CHOOSE 恰好是该策略的另一个受害者。

标签: sql sql-server database random


【解决方案1】:

我认为您已超出索引。并且您假设RAND() 在 NOT 时为每次执行相同查询返回相同的值。问题在于这里的逻辑,而不是函数'CHOOSE'

测试和玩这个,看看每个字段的值以及它是如何工作的:

SELECT
    CHOOSE(FLOOR(RAND() * 4) + 1, 5, 15, 16, 17,'OUT') AS UnknownRandomResult,
    RAND() * 4 as Rand4,
    FLOOR(RAND() * 4)  as Floor4,
    FLOOR(RAND() * 4) + 1 as Floor4Plus1,
        RAND() * 4 as Rand4_2,
    FLOOR(RAND() * 4)  as Floor4_2,
    FLOOR(RAND() * 4) + 1 as Floor4Plus1_2

阅读更多信息: https://docs.microsoft.com/en-us/sql/t-sql/functions/logical-functions-choose-transact-sql?view=sql-server-ver15

更新:

我建议用一些 IF NULL 默认值来修复 NULL。

【讨论】:

    猜你喜欢
    • 2018-09-03
    • 2023-03-31
    • 1970-01-01
    • 2021-07-05
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    相关资源
    最近更新 更多