【问题标题】:Use comparison signs inside a sql case statement在 sql case 语句中使用比较符号
【发布时间】:2013-01-15 21:57:26
【问题描述】:

我正在寻找一种使用小于和大于符号在 sql 选择查询中构建 case 语句的方法。比如我想根据一个变量来选择排名:

DECLARE @a INT
SET @a = 0

SELECT CASE 
         WHEN @a < 3 THEN 0
         WHEN @a = 3 THEN 1
         WHEN @a > 3 THEN 2
       END

我想写成:

DECLARE @a INT
SET @a = 0

SELECT CASE @a
         WHEN < 3 THEN 0
         WHEN 3 THEN 1
         WHEN > 3 THEN 2
       END

...但是 SQL 不允许我以这种方式使用 符号。有没有办法可以做到这一点是 SQL 2005,还是我需要像第一个那样使用代码。

只需要代码一次的原因是因为它会使代码更具可读性/可维护性,还因为我不确定 SQL 服务器是否必须为每个 CASE 语句运行计算。

我正在寻找等效的 VB.NET 案例语句:

Select Case i
    Case Is < 100
        p = 1
    Case Is >= 100
        p = 2
End Select

也许这在 SQL 中是不可能的,没关系,我只是想确认一下。

【问题讨论】:

  • CASE 在大多数其他编程语言中的工作方式与 CASE 或 SWITCH 类似。我看不出你的需要。
  • 对不起,我的问题结束了。如果您仍然不明白我想要实现的目标,请告诉我
  • CASE 表达式只会在其中一个为真之前短路和评估案例。我认为另一种方法没有任何优势。
  • 我知道它只会选择第一个评估为 true 的案例,我的问题是我希望它根据小于或大于符号评估 true,而不是评估等于具体值。在这个例子中,写 WHEN @a
  • 正如我多次提到的,我的代码并不像@a 那样简单,它实际上是一个复杂的方程:(((Col1 * Col2) + col3-col2)/col4)。这需要为每一行计算。我同意第一个语句完美运行,但是当您添加实际列名的长度时,它变得难以阅读

标签: sql sql-server sql-server-2005 tsql


【解决方案1】:

您可以将SIGN 函数用作

DECLARE @a INT
SET @a = 0

SELECT CASE SIGN(@a - 3)
         WHEN -1 THEN 0
         WHEN 0 THEN 1
         WHEN 1 THEN 2
       END

如果 @a 小于 3,则 @a - 3 产生负整数,其中 SIGN 返回 -1。

如果 @a 大于或等于 3,则 SIGN 分别返回 0 或 1。


如果您想要的输出是 0、1 和 2,那么您可以进一步简化:

DECLARE @a INT
SET @a = 0

SELECT SIGN(@a - 3) + 1

【讨论】:

  • 我看不出这是如何更易于维护的。任何了解 SQl 的人都会发现 OP 不喜欢但更清晰的原始语句。
  • @HLGEM 如果@a 只是一个简单的表达式,我也同意你的看法,但根据OP,@a 是一个冗长的复杂表达式,他不想看到重复三遍在案例陈述中。所以,我想我或 Andriy M 的解决方案适合解决他的问题。
  • 嗯,对我来说这很完美。我必须确定最近在荷兰发生变化的增值税百分比。我只是将产品的交货日期与应使用新增值税百分比的日期(使用 datediff 函数)进行比较,然后使用 sign() 构造来确定正确的增值税百分比。对我来说似乎是一个足够优雅的解决方案。
【解决方案2】:

SIGN 用作suggested by @Jose Rui Santos 似乎是一个不错的解决方法。另一种方法是为表达式分配别名,使用子选择并在外部选择中测试表达式(使用其别名):

SELECT
  …,
  CASE
    WHEN expr < 3 THEN …
    WHEN expr > 3 THEN …
  END AS …
FROM (
  SELECT
    …,
    a complex expression AS expr
  FROM …
  …
)

【讨论】:

    【解决方案3】:
    SELECT 
    CASE 
    WHEN ColumnName >=1 and ColumnName <=1 THEN 'Fail'
    WHEN ColumnName >=6 THEN 'Pass'
    ELSE 'Test'
    END
    FROM TableName
    

    【讨论】:

    • 最初的问题是如何让条件不出现在每一行。这实际上并没有回答这个问题,因为我仍然需要在 2 行上重复方程式并假设 else
    • 我不能对此表示赞同,因为它不一定能解决原始问题,但它解决了我的问题。谢谢。只需将 ColumnName 从“CASE”行移到每个“WHEN”行即可。
    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多