0

I am having problem in writing (and understanding) CASE equivalent of DECODE for the example below.

Lets say we have the following table.

CREATE TABLE Employee(
    first_name VARCHAR2(15) CONSTRAINT nn_first_name NOT NULL,
    last_name VARCHAR2(15) CONSTRAINT nn_last_name NOT NULL,
    sex VARCHAR2(1) CONSTRAINT check_sex CHECK(sex IN ('M', 'F')),
    ID VARCHAR2(15) CONSTRAINT pk_ID PRIMARY KEY,
    boss_ID VARCHAR2(15) CONSTRAINT fk_ID_empl_to_empl REFERENCES Employee(ID)); 

Name       Null     Type         
---------- -------- ------------ 
FIRST_NAME NOT NULL VARCHAR2(15) 
LAST_NAME  NOT NULL VARCHAR2(15) 
SEX                 VARCHAR2(1)  
ID         NOT NULL VARCHAR2(15) 
BOSS_ID             VARCHAR2(15) 

Now, I woud like to run a report which displays information about bosses and subordinates of male employees. In case if employee does not have a subordinate, then it should display (null), same goes for an employee who does not have a boss - boss of the whole company.

The above can be achieved using DECODE:

SELECT E1.last_name Boss,
    E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
    ON E1.ID = E2.boss_ID
WHERE
    DECODE(E1.ID, NULL, 'M', E1.sex) = 'M' AND
    DECODE(E2.ID, NULL, 'M', E2.sex) = 'M';

The above function will change all NULL values into 'M' and match rows where 'M' = 'M' for 'Boss' and 'Subordinates' columns.

I am unable to write equivalent statement using CASE. The one I got:

SELECT E1.last_name Boss,
    E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
    ON E1.id = E2.boss_id
WHERE
    (CASE
    WHEN E1.ID = 'NULL' THEN 'M' ELSE E1.sex END) = 'M' 
    AND
    (CASE 
    WHEN E2.ID = 'NULL' THEN 'M' ELSE E2.sex END) = 'M';

I seem to be misunderstanding usage of CASE as it returns less rows - without (null) values.

Plump Worm
  • 233
  • 3
  • 13

2 Answers2

0
SELECT E1.last_name Boss,
    E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
    ON E1.id = E2.boss_id
WHERE
    (CASE
    WHEN E1.ID is null THEN 'M' ELSE E1.sex END) = 'M' 
    AND
    (CASE 
    WHEN E2.ID is null THEN 'M' ELSE E2.sex END) = 'M';

When comparing a value to null, use IS NULL and IS NOT NULL .

You can read about it here.

sagi
  • 40,026
  • 6
  • 59
  • 84
0

You don't need case or decode for this:

WHERE (E1.ID IS NULL OR E1.sex = 'M') AND
      (E2.ID IS NULL OR E2.sex = 'M') 

Your logic would work as well, except that you have put the NULL in single quotes. The string values with four characters N,U, L, L is not the same as the built-in value NULL.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786