3

这是关于在 MS SQL [CASE WHEN X = Y] 和 [CASE X WHEN Y] 中使用 SELECT CASE 的两种方法的问题

我正在尝试根据字段的值定义字段的存储桶。我需要使用范围,因此有必要使用“<”或“>”标识符。

作为一个简单的例子,我知道它是这样工作的:

SELECT CASE WHEN x < 0 THEN 'a' WHEN X > 100 THEN 'b' ELSE 'c' END

现在我要写很多这些,会有3个以上的桶,而且字段名很长,所以这变得很难保持干净和易于理解。我希望使用 select 命令的另一种方式,但在我看来,我只能将它与 equals 一起使用:

SELECT CASE X WHEN 0 then 'y' ELSE 'z' END

但是我怎样才能使用这种形式来指定范围条件呢?就像是:

SELECT CASE X WHEN < 0 THEN 'a' WHEN > 100 THEN 'b' ELSE "c" END

这个不行。

谢谢你!

4

4 回答 4

3

作为一种替代方法,请记住,可以对“简单”CASE 语句的输入值进行数学运算。为此,我经常使用 ROUND,如下所示:

SELECT 
  CASE ROUND(X, -2, 1)
    WHEN 0   THEN 'b' -- 0-99
    WHEN 100 THEN 'c' -- 100-199
    ELSE 'a'          -- 200+
  END

由于您的示例包括正负开放式范围,因此这种方法可能不适合您。

还有另一种方法:如果您只考虑 SELECT 语句中的可读性,您可以编写一个标量值函数来隐藏所有混乱:

CREATE FUNCTION dbo.ufn_SortValuesIntoBuckets (@inputValue INT) RETURNS VARCHAR(10) AS
BEGIN
    DECLARE @outputValue VARCHAR(10);

    SELECT @outputValue = 
        CASE WHEN @inputValue < 0 THEN 'a'
             WHEN @inputValue BETWEEN 0 AND 100 THEN 'b'
             WHEN @inputValue > 100 THEN 'c'
        END;

    RETURN @outputValue;
END;
GO

所以现在你的 SELECT 语句就是:

SELECT dbo.ufn_SortValuesIntoBuckets(X); 

One final consideration: I have often found, during benchmark testing, that the "searched" form (which you are trying to avoid) actually has better performance than the "simple" form, depending how many CASEs you have. So if performance is a consideration, it might be worth your while to do a little benchmarking before you change things around too much.

于 2013-09-30T18:51:53.527 回答
1

没有这种“第三种形式” CASE- 仅支持搜索简单的情况*

即使您应用条件的变量始终相同,您也需要使用搜索到的类型(即具有单独的条件)。

如果您希望在X表示复杂表达式时避免 SQL 中的重复,请使用WITH子句或嵌套查询来为您选择的表达式分配名称。


*你的第一个例子的正式名称是“搜索CASE表达式”;您的第二个示例称为“简单CASE表达式”。

于 2013-09-30T18:08:16.357 回答
1

使用 BETWEENs 看起来不会那么糟糕:

SELECT CASE
WHEN X < 0 THEN 'a'
WHEN X BETWEEN 0   AND 100 THEN 'b' 
WHEN X BETWEEN 100 AND 200 THEN 'c' 
ELSE 'd' END
于 2013-09-30T18:16:49.473 回答
0

That is actually very interesting question. It resembles C# 9.0 relational pattern

SELECT CASE X WHEN < 0 THEN 'a' 
              WHEN > 100 THEN 'b' 
              ELSE 'c' 
        END

C# 9.0
DeliveryTruck t when t.GrossWeightClass switch
{
    > 5000 => 10.00m + 5.00m,
    < 3000 => 10.00m - 2.00m,
    _ => 10.00m,
},

SQL CASE expression as mentioned in previous answers has two forms: simple and searched.

But SQL standard defines also SQL:2003 Extended CASE expression(F262). This feature is barely adopted by major vendors.

case — Conditional Expressions by Markus Winand

The so-called extended case accepts a comparison operator right after when and thus lifts the limitation that simple case always uses equals (=) comparisons. The following example uses the less than operator (<) to map values into intervals. It also relies on the precedence of when clauses: the first true condition wins.

CASE x WHEN < 0   THEN '< 0'
       WHEN < 10  THEN '[0, 10['
       WHEN < 100 THEN '[10, 100['
       ELSE '>100'
END
于 2020-05-21T08:12:40.340 回答