【问题标题】:Comparison sign 'greater than' and 'equal to' in CASE SQL StatementCASE SQL 语句中的比较符号“大于”和“等于”
【发布时间】:2019-06-02 04:13:00
【问题描述】:

我是 SQL Server 新手,这是我的第一篇文章。
使用 Case 语句时,我收到消息“'=' 附近的语法不正确。这是我的代码示例:

  Select * , CASE 
    when a > b THEN b = a
    when c > d THEN d = c
    when e > f THEN f = e
    when g > h THEN h = g
    when i > j THEN j = i
    when k > l THEN l = k
    when m > n THEN n = m
    when o > p THEN p = o

END as value
INTO #temptable
From #atemptable

提前感谢您的帮助!

【问题讨论】:

  • 您好 MsAB2,您能先解释一下您要做什么吗?
  • 我正在尝试评估一个表达式,它正在检查一个变量是否大于另一个。如果是,则将较小的变量设置为等于较大的变量。有道理?这回答了你的问题了吗?这是我试图在 SQL 中重做的另一种语言 (SAS) 的现有代码。
  • 嘿,我可以读到那种,但你不能在 SELECT 语句中这样做。它只存在于 SELECT 的东西。没有分配或任何可能的事情,这就是您拥有 UPDATE 语句的目的。
  • 好的。谢谢TT。我将研究 UPDATE 语句。

标签: tsql comparison-operators case-statement


【解决方案1】:

尚不清楚您是否希望THEN 部分作为分配或比较。不管怎样,这是不可能的,THEN 部分只能是一个表达式。我假设你想要一个任务。看起来您不想更新#atemptable,您只需要#temptable 中的新值。在这种情况下,您可以使用单独的 CASE 表达式,如下所示:

SELECT  A, CASE WHEN A > B THEN A ELSE B END AS B,
        C, CASE WHEN C > D THEN C ELSE D END AS D
END AS value
INTO #temptable
FROM #atemptable

【讨论】:

  • 迂腐深入文档:比较,例如pi >= e,是一个expression,其结果数据类型为Boolean。正如文档所述:“与其他 SQL Server 数据类型不同,Boolean 数据类型不能指定为表列或变量的数据类型,也不能在结果集中返回。” ...
  • ... 要完成循环,case 的文档提供:“结果表达式 是任何有效的表达式。”所以 case 结果表达式可以是相等比较,但它不能,因为不能返回 Boolean 数据类型,但它是“有效表达式”,但在该上下文中无效。 “拔头发”的表情在哪里?
  • 好吧,看起来SELECT 1 WHERE CASE WHEN 1=1 THEN 1=0 ELSE 1=1 END 应该可以工作,但它没有。 ?
  • 它会几乎看起来那样。问题是“布尔数据类型不能指定为表列或变量的数据类型,不能在结果集中返回”。如果可以,那么select 1 > 0; 将起作用,因为select list 可以包含表达式。由于您可以创建 Boolean 表达式,但永远无法保留 Boolean 值,因此文档听起来像是关于“是”是什么的争论。
  • A where 子句 search expression <predicate> 不能是 <expression> 没有一些其他部分/部分,例如与另一个<expression> 进行比较,因此... where case ... end; 无效。由于case 表达式的返回值不能是Boolean,因此尝试您的语句仍然会导致then 子句中的错误,这是我的第二条评论通过引用Microsoft 的福音而不清楚的问题。 (我现在有 Microsoft Pattern Baldness。)
【解决方案2】:

你不仅需要 TT 在 cmets 中写的更新语句,你也不能使用 case 表达式作为流控制。

case 表达式根据条件返回一个值。 case 表达式的 Then 部分内的操作仅在返回值时才有效。

您可能正在寻找这样的东西:

UPDATE #temptable
SET B = CASE A > B Than A ELSE B END
   ,D = IIF(C > D, C, D) -- IIF is syntactic sugar for simple case expressions
 -- more of the same for all other columns

【讨论】:

  • 感谢您的反馈。我仍在努力解决这个问题。一切解决后,我会提供更新。
【解决方案3】:

你需要知道关于 T-SQL 中CASE 语句的重要说明:

CASE 表达式按顺序计算其条件,并在满足条件的第一个条件处停止

在这里阅读更多:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql?view=sql-server-2017

因此,根据上述提示,您的CASE 不会按预期执行,因为如果我们假设您的第一个条件(a>b)为真,那么CASE 的评估将停止并你不会得到其他条件的结果。

要解决它,您需要为每个条件编写一个CASE 语句,如下所示:

SELECT *,
       CASE WHEN a > b THEN b ELSE a END AS AorB,
       CASE WHEN c > d THEN d ELSE c END AS CorD,
       CASE WHEN e > f THEN f ELSE e END AS EorF,
       CASE WHEN g > h THEN h ELSE g END AS GorH,
       CASE WHEN i > j THEN j ELSE i END AS JorI,
       CASE WHEN k > l THEN l ELSE k END AS LorK,
       CASE WHEN m > n THEN n ELSE m END AS MorN,
       CASE WHEN o > p THEN p ELSE o END AS OorP
INTO #temptable
From #atemptable

更新

正如你在评论中提到的:

我正在尝试评估一个表达式,它正在检查一个变量是否大于另一个。如果是则设置较小的变量等于较大的变量

所以故事完全不同,你应该使用这样的方法:

假设我们有一组变量定义如下:阅读更多关于 T-SQL 中的变量定义:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql?view=sql-server-2017

DECLARE 
    @a INT = 2, @b INT = 1,
    @c INT = 3, @d INT = 4,
    @e INT = 6, @f INT = 5,
    @g INT = 7, @h INT = 8,
    @i INT = 10,@j INT = 9,
    @k INT = 12,@l INT = 11,
    @m INT = 13,@n INT = 14,
    @o INT = 16,@p INT = 15

为了评估您的场景,我们需要编写如下代码:

       SET @b= CASE WHEN @a > @b THEN @a ELSE @b END
       SET @d= CASE WHEN @c > @d THEN @c ELSE @d END
       SET @f= CASE WHEN @e > @f THEN @e ELSE @f END
       SET @h= CASE WHEN @g > @h THEN @g ELSE @g END
       SET @j= CASE WHEN @i > @j THEN @i ELSE @i END
       SET @l= CASE WHEN @k > @l THEN @k ELSE @k END
       SET @n= CASE WHEN @m > @n THEN @m ELSE @m END
       SET @p= CASE WHEN @o > @p THEN @o ELSE @o END

所以如果我们执行 SELECT,我们会看到结果:

       SELECT @a,@b, ...

【讨论】:

  • 感谢您的反馈。我仍在研究这个问题,并将确定您提出的内容是否有效。我会及时通知你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多