Home All Groups Group Topic Archive Search About

Mutually Exclusive CASE???

Author
12 Aug 2005 3:45 PM
wnfisba
Sure looks as though CASE is Mutually Exclusive...in other words, when a
condition is hit, it bounces out and does not continue.

I have a case where Race is checked. SO for some people...
Black='X'
White='X'

Obviously I have more. I want to transpose 'X's to numbers. White=5,
Black=3, etc..

Is there any easy way to do this in a CASE statement so that it will look at
all columns???

For Example, I would like to CASE Black and if its 'X', make the result
column 3 and then CASE White and if that too is 'X' then the result column
should be "3,5"???

Any help would be GREATLY appreciated!

Author
12 Aug 2005 3:58 PM
Adam Machanic
See Aaron Bertrand's reply to your other post.

If you do insist on doing this in the database, you'll need one CASE
expression per column.


--
Adam Machanic
SQL Server MVP
http://www.datamanipulation.net
--


Show quote
"wnfisba" <wnfi***@discussions.microsoft.com> wrote in message
news:E937CE4D-4E5E-4D59-89B5-B7F9165C1368@microsoft.com...
> Sure looks as though CASE is Mutually Exclusive...in other words, when a
> condition is hit, it bounces out and does not continue.
>
> I have a case where Race is checked. SO for some people...
> Black='X'
> White='X'
>
> Obviously I have more. I want to transpose 'X's to numbers. White=5,
> Black=3, etc..
>
> Is there any easy way to do this in a CASE statement so that it will look
at
> all columns???
>
> For Example, I would like to CASE Black and if its 'X', make the result
> column 3 and then CASE White and if that too is 'X' then the result column
> should be "3,5"???
>
> Any help would be GREATLY appreciated!
Author
15 Aug 2005 8:15 AM
Robert Klemme
Adam Machanic wrote:
> See Aaron Bertrand's reply to your other post.
>
> If you do insist on doing this in the database, you'll need one CASE
> expression per column.

.... or introduce a mapping table.  This might or might not be faster -
depending on your data and the types of queries.

    robert

Show quote
>
> --
> Adam Machanic
> SQL Server MVP
> http://www.datamanipulation.net
>
> "wnfisba" <wnfi***@discussions.microsoft.com> wrote in message
> news:E937CE4D-4E5E-4D59-89B5-B7F9165C1368@microsoft.com...
>> Sure looks as though CASE is Mutually Exclusive...in other words,
>> when a condition is hit, it bounces out and does not continue.
>>
>> I have a case where Race is checked. SO for some people...
>> Black='X'
>> White='X'
>>
>> Obviously I have more. I want to transpose 'X's to numbers. White=5,
>> Black=3, etc..
>>
>> Is there any easy way to do this in a CASE statement so that it will
>> look at all columns???
>>
>> For Example, I would like to CASE Black and if its 'X', make the
>> result column 3 and then CASE White and if that too is 'X' then the
>> result column should be "3,5"???
>>
>> Any help would be GREATLY appreciated!
Author
12 Aug 2005 6:23 PM
--CELKO--
>> Sure looks as though CASE is Mutually Exclusive...in other words, when a condition is hit, it bounces out and does not continue. <<

The CASE expression is an *expression* and not a control statement;
that is, it returns a value of one datatype.  SQL-92 stole the idea and
the syntax from the ADA programming language.  Here is the BNF for a
<case specification>:

<case specification> ::= <simple case> | <searched case>

<simple case> ::=
    CASE <case operand>
      <simple when clause>...
      [<else clause>]
    END

<searched case> ::=
    CASE
      <searched when clause>...
      [<else clause>]
    END

<simple when clause> ::= WHEN <when operand> THEN <result>

<searched when clause> ::= WHEN <search condition> THEN <result>

<else clause> ::= ELSE <result>

<case operand> ::= <value expression>

<when operand> ::= <value expression>

<result> ::= <result expression> | NULL

<result expression> ::= <value expression>

The searched CASE expression is probably the most used version of the
expression.  The WHEN ... THEN ... clauses are executed in left to
right order.  The first WHEN clause that tests TRUE returns the value
given in its THEN clause.  And, yes, you can nest CASE expressions
inside each other.  If no explicit ELSE clause is given for the CASE
expression, then the database will insert a default ELSE NULL clause.
If you want to return a NULL in a THEN clause, then you must use a CAST
(NULL AS <datatype>) expression.  I recommend always giving the ELSE
clause, so that you can change it later when you find something
explicit to return.

The <simple case expression> is defined as a searched CASE expression
in which all the WHEN clauses are made into equality comparisons
against the <case operand>.  For example

  CASE iso_sex_code
  WHEN 0 THEN 'Unknown'
  WHEN 1 THEN 'Male'
  WHEN 2 THEN 'Female'
  WHEN 9 THEN 'N/A'
  ELSE NULL END

could also be written as:

  CASE
  WHEN iso_sex_code = 0 THEN 'Unknown'
  WHEN iso_sex_code = 1 THEN 'Male'
  WHEN iso_sex_code = 2 THEN 'Female'
  WHEN iso_sex_code = 9 THEN 'N/A'
  ELSE NULL END

There is a gimmick in this definition, however.  The expression

CASE foo
WHEN 1 THEN 'bar'
WHEN NULL THEN 'no bar'
END

becomes

CASE WHEN foo = 1 THEN 'bar'
      WHEN foo = NULL THEN 'no_bar'  -- error!
      ELSE NULL END

The second WHEN clause is always UNKNOWN.

The SQL-92 Standard defines other functions in terms of the CASE
expression, which makes the language a bit more compact and easier to
implement.  For example, the COALESCE () function can be defined for
one or two expressions by

1) COALESCE (<value exp #1>) is equivalent to (<value exp #1>)

2) COALESCE (<value exp #1>, <value exp #2>) is equivalent to

   CASE WHEN <value exp #1> IS NOT NULL
        THEN <value exp #1>
        ELSE <value exp #2> END

then we can recursively define it for (n) expressions, where (n >= 3),
in the list by

COALESCE (<value exp #1>, <value exp #2>, . . ., n), as equivalent to:

   CASE WHEN <value exp #1> IS NOT NULL
        THEN <value exp #1>
        ELSE COALESCE (<value exp #2>, . . ., n)
   END

Likewise, NULLIF (<value exp #1>, <value exp #2>) is equivalent to:

   CASE WHEN <value exp #1> = <value exp #2>
        THEN NULL
        ELSE <value exp #1> END

It is important to be sure that you have a THEN or ELSE clause with a
datatype that the compiler can find to determine the highest datatype
for the expression.

A trick in the WHERE clause is use it for a complex predicate with
material implications.

WHERE CASE
      WHEN <search condition #1>
      THEN 1
      WHEN <search condition #2>
      THEN 1
       ...
      ELSE 0 END  = 1

Gert-Jan Strik posted some exampels of how ISNULL() and COALESCE() on
2004 Aug 19

CREATE TABLE #t(a CHAR(1));
INSERT INTO #t VALUES (NULL);
SELECT ISNULL(a,'abc') FROM #t;
SELECT COALESCE(a, 'abc') FROM #t;
DROP TABLE #t;

He always use COALESCE, with the exception of the following type of
situation, because of its performance consequences:

SELECT ...,
  ISNULL((SELECT COUNT(*)  -- or other aggregate
           FROM B
          WHERE B.key = A.key), 0)
FROM A;

Likewise, Alejandro Mesa cam up with this example:

SELECT 13 / COALESCE(CAST(NULL AS INTEGER), 2.00); -- promote to
highest type (decimal)
SELECT 13 / ISNULL(CAST(NULL AS INTEGER), 2.00); -- promote to first
type (integer)

AddThis Social Bookmark Button