select case card_number when null then 'NULL' else 'NOT NULL' end as card, count(*)
from credit_card
group by case card_number when null then 'NULL' else 'NOT NULL' end
order by 1;
This looks pretty straightforward. The case is on the card_number when the value is null change the output to the string 'NULL' else change the output to 'NOT NULL' and count the occurrences of each.
Every time I ran this in every database, it showed all records as 'NOT NULL' which shouldn't be correct. I circled back and changed the case to a decode to see what it would look like. That statement was:
select decode(card_number,null,'NULL','NOT NULL') as card, count(*)
from credit_card
group by decode(card_number,null,'NULL','NOT NULL')
order by 1;
The logic is the same but we use an oracle standard decode function instead of the CASE keyword. And our results look more like we'd expect. Some are null and some are not null. So, what went wrong with the CASE statement? Some of you might have already picked up on what I did wrong. The null in the ...Case card_number when null... part was not checking if card_number was null, it was saying when there is nothing to do change the variable to 'NULL'. If we look to the NULL statement in PL/SQL that might help us understand.
create or replace procedure validnullproc as
Begin
Null;
End;
This is a valid procedure that does fuck all. So basically I was inserting a null chunk of code into my Case statement. Here is a statement that shows a couple of other options:
SELECT
CASE card_number
WHEN NULL
THEN 'NULL'
ELSE 'NOT NULL'
END AS card,
DECODE(card_number,NULL,'NULL','NOT NULL') as decodecard,
nvl2(card_number, 'NOT NULL', 'NULL') as nvl2card
FROM credit_card
WHERE card_number IS NULL
AND rownum < 11
UNION
SELECT
CASE card_number
WHEN NULL
THEN 'NULL'
ELSE 'NOT NULL'
END AS card,
DECODE(card_number,NULL,'NULL','NOT NULL'),
nvl2(card_number, 'NOT NULL', 'NULL')
FROM credit_card
WHERE card_number IS NOT NULL
AND rownum < 11;
Results:
"CARD" "DECODECARD""NVL2CARD"
"NOT NULL" "NOT NULL" "NOT NULL"
"NOT NULL" "NULL" "NULL"
So, my fancy Case statement to pull the CARD column above is basically just saying always Print 'NOT NULL'. However, both the DECODE and the NVL2 functions resolve to the correct values and I think NVL2 is the better option in this case. And I must admit that NVL2 is new to me, personally.
Well, thanks for tuning into my adventure's with Oracle. Now, go forth and use Oracle wisely.
No comments:
Post a Comment