SQL中的case语句,如何返回多个变量?

yzh*_*ang 23 sql sql-server

我想在我的case语句中返回多个值,例如:

SELECT
  CASE
    WHEN <condition 1> THEN <value1=a1, value2=b1>
    WHEN <condition 2> THEN <value1=a2, value2=b2>
    ELSE <value1=a3, value3=b3>
  END
FROM <table>
Run Code Online (Sandbox Code Playgroud)

当然我可以多次编写案例条件,每次都返回一个值.但是,因为我有许多条件需要适合,比如说100.一次又一次重复案件条件并不好.

我想问的另一个问题,如果一条记录符合多个条件,会发生什么?这是否意味着它将返回所有这些或只是最后一个?例如,条件1可能成为条件2的子集.会发生什么?

Mat*_*lie 13

不幸的是,基本方法是重复自己.

SELECT
  CASE WHEN <condition 1> THEN <a1> WHEN <condition 2> THEN <a2> ELSE <a3> END,
  CASE WHEN <condition 1> THEN <b1> WHEN <condition 2> THEN <b2> ELSE <b3> END
FROM 
  <table> 
Run Code Online (Sandbox Code Playgroud)

幸运的是,大多数RDBMS都足够聪明,不必多次评估条件.这只是多余的打字.


在MS SQL Server(2005+)中,您可以使用CROSS APPLY作为替代方法.虽然我不知道它是多么高效......

SELECT
  *
FROM
  <table>
CROSS APPLY
  (
   SELECT a1, b1 WHERE <condition 1>
   UNION ALL
   SELECT a2, b2 WHERE <condition 2>
   UNION ALL
   SELECT a3, b3 WHERE <condition 3>
  )
  AS case_proxy
Run Code Online (Sandbox Code Playgroud)

这里明显的缺点是没有等效的ELSE,并且所有条件都可以返回值,所以它们需要被框定,以便一次只能有一个是真的.


编辑

如果Yuck的答案改为UNION而不是JOIN方法,那么它就变得非常相似了.然而,主要区别在于它只扫描输入数据集一次,而不是每个条件扫描一次(在您的情况下为100次).


编辑

我也注意到你可能意味着CASE语句返回的值是固定的.匹配相同条件的所有记录在value1和value2中获得完全相同的值.这可以像这样形成......

WITH
  checked_data AS
(
  SELECT
    CASE WHEN <condition1> THEN 1
         WHEN <condition2> THEN 2
         WHEN <condition3> THEN 3
         ...
         ELSE                   100
    END AS condition_id,
    *
  FROM
    <table>
)
,
  results (condition_id, value1, value2) AS
(
   SELECT 1, a1, b1
   UNION ALL
   SELECT 2, a2, b2
   UNION ALL
   SELECT 3, a3, b3
   UNION ALL
   ...
   SELECT 100, a100, b100
)
SELECT
  *
FROM
  checked_data
INNER JOIN
  results
    ON results.condition_id = checked_data.condition_id
Run Code Online (Sandbox Code Playgroud)


Yuc*_*uck 6

一个CASE声明只能返回一个值.

您可以将其转换为子查询,然后将JOIN其转换为您正在使用的任何其他关系.例如(使用SQL Server 2K5 + CTE):

WITH C1 AS (
  SELECT a1 AS value1, b1 AS value2
  FROM table
  WHERE condition1
), C2 AS (
  SELECT a2 AS value1, b2 AS value2
  FROM table
  WHERE condition2
), C3 AS (
  SELECT a3 AS value1, b3 AS value2
  FROM table
  WHERE condition3
)
SELECT value1, value2
FROM -- some table, joining C1, C2, C3 CTEs to get the cased values
;
Run Code Online (Sandbox Code Playgroud)


JNK*_*JNK 6

CASE根据定义,只返回一个值.永远.

它也(几乎总是)短路,这意味着如果满足您的第一个条件,则不会运行其他检查.