case statement in SQL, how to return multiple variables?

后端 未结 9 2178
甜味超标
甜味超标 2020-12-05 13:40

I would like to return multiple values in my case statement, such as :

SELECT
  CASE
    WHEN  THEN 
    WHEN          


        
相关标签:
9条回答
  • 2020-12-05 14:01

    Depending on your use case, instead of using a case statement, you can use the union of multiple select statements, one for each condition.

    My goal when I found this question was to select multiple columns conditionally. I didn't necessarily need the case statement, so this is what I did.

    For example:

      SELECT
        a1,
        a2,
        a3,
        ...
      WHERE <condition 1>
        AND (<other conditions>)
      UNION
      SELECT
        b1,
        b2,
        b3,
        ...
      WHERE <condition 2>
        AND (<other conditions>)
      UNION
      SELECT
      ...
    -- and so on
    
    

    Be sure that exactly one condition evaluates to true at a time.

    I'm using Postgresql, and the query planner was smart enough to not run a select statement at all if the condition in the where clause evaluated to false (i.e. only one of the select statement actually runs), so this was also performant for me.

    0 讨论(0)
  • 2020-12-05 14:08

    CASE by definition only returns a single value. Ever.

    It also (almost always) short circuits, which means if your first condition is met no other checks are run.

    0 讨论(0)
  • 2020-12-05 14:08

    or you can

    SELECT
      String_to_array(CASE
        WHEN <condition 1> THEN a1||','||b1
        WHEN <condition 2> THEN a2||','||b2
        ELSE a3||','||b3
      END, ',') K
    FROM <table>
    
    0 讨论(0)
  • 2020-12-05 14:14

    A CASE statement can return only one value.

    You may be able to turn this into a subquery and then JOIN it to whatever other relations you're working with. For example (using SQL Server 2K5+ CTEs):

    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
    ;
    
    0 讨论(0)
  • 2020-12-05 14:16

    The basic way, unfortunately, is to repeat yourself.

    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> 
    

    Fortunately, most RDBMS are clever enough to NOT have to evaluate the conditions multiple times. It's just redundant typing.


    In MS SQL Server (2005+) you could possible use CROSS APPLY as an alternative to this. Though I have no idea how performant it is...

    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
    

    The noticable downside here is that there is no ELSE equivalent and as all the conditions could all return values, they need to be framed such that only one can ever be true at a time.


    EDIT

    If Yuck's answer is changed to a UNION rather than JOIN approach, it becomes very similar to this. The main difference, however, being that this only scans the input data set once, rather than once per condition (100 times in your case).


    EDIT

    I've also noticed that you may mean that the values returned by the CASE statements are fixed. All records that match the same condition get the exact sames values in value1 and value2. This could be formed like this...

    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
    
    0 讨论(0)
  • 2020-12-05 14:17

    You could use a subselect combined with a UNION. Whenever you can return the same fields for more than one condition use OR with the parenthesis as in this example:

    SELECT * FROM
      (SELECT val1, val2 FROM table1 WHERE (condition1 is true) 
                                        OR (condition2 is true))
    UNION
    SELECT * FROM
      (SELECT val5, val6 FROM table7 WHERE (condition9 is true) 
                                        OR (condition4 is true))
    
    0 讨论(0)
提交回复
热议问题