MySQL how to deal with nulls passed into a case statement - mysql

I'm using a case statement with MySQL.
When f.winner field is NULL, it returns "Loss" instead of f.method. So it seems as though the MySQL case statement can't handle blanks and nulls like this.
(
CASE f.winner
WHEN :fighter_id THEN "Win"
WHEN NULL OR "0" THEN f.method
ELSE "Loss"
END
) AS result,
Sometimes both f.winner and f.method are blank, and I just want the result to return as blank in those situations.

You could use IFNULL function and remove the NULL from your WHEN clause:
(
CASE IFNULL(f.winner, "0")
WHEN :fighter_id THEN "Win"
WHEN "0" THEN f.method
ELSE "Loss"
END
) AS result,

Related

MySQL JSON_EXTRACT subquery not working when enclosed in IFNULL

Goal
Select a value based on a value returned by a subquery that is using JSON_EXTRACT which either returns a 'value' or NULL. IFNULL should be able to allow you to set a default value when the JSON_EXTRACT does not return a result.
Problem
When using a subquery that uses JSON_EXTRACT and returns a result, will return nothing when enclosed in IFNULL ignoring the default value.
Consider the following case
We want to select a SubscriptionPlan.name based on an identifier that is the result of a subquery using JSON_EXTRACT.
SELECT
subscriptionplan.name
FROM
SubscriptionPlan AS subscriptionplan
WHERE
subscriptionplan.identifier = (
SELECT
JSON_EXTRACT(product.data, '$.identifier')
FROM
Subscription AS subscription
JOIN
Product AS product ON product.productid = subscription.productid
WHERE
subscription.status = 'ACTIVE'
AND
subscription.ownerid = :userId
)
Case 1. SUCCESS without IFNULL
Subscription exists with status 'ACTIVE' and 'userId'
- Subquery result: 'PRO' and thus finds the SubscriptionPlan
- Final result: 'Professional'
Case 2. NOT FOUND without IFNULL
Subscription not found with status 'ACTIVE' and 'userId'
- Subquery result: NULL and thus does not find a SubscriptionPlan
- Final result: NULL
Now we add the IFNULL operation to default to 'FREE' subscription plan:
subscriptionplan.identifier = IFNULL(
( SELECT JSON_EXTRACT ... ),
'FREE'
)
Case 3. SUCCESS with IFNULL
Subscription exists with status 'ACTIVE' and 'userId'
- Subquery result: NULL even though the subscription was found !???
- Final result: NULL
Case 4. NOT FOUND with IFNULL
Subscription not found with status 'ACTIVE' and 'userId'
- Subquery result: FREE and thus finds the FREE SubscriptionPlan
- Final result: 'Free'
The IFNULL expression nullifies the subquery result, and it does not default to 'FREE'.
My thoughts are as follows:
Case 4: is using the IFNULL default value string 'FREE' and therefore works as intended
Case 3: subquery should return PRO and even if it returns NULL, it should default to 'FREE', neither happens
Maybe adding the IFNULL query adds another nesting layer where
What i've tried and did not work:
IF( () IS NULL, 'do stuff', 'do other stuff')
IF( ISNULL(<query<), 'do stuff', 'do other stuff')
IF( () = null , ..., ...)
IF( () = NULL , ..., ...)
IF( () = 'null' , ..., ...)
IF( () = 'NULL' , ..., ...)
Also according to Can't detect null value from JSON_EXTRACT:
IF ( JSON_EXTRACT(product.data, '$.identifier') = CAST('null' AS JSON), ...., ... )
All failures! Why is JSON_EXTRACT subquery not working when enclosed in IFNULL?
I've found out what caused the error.
JSON_EXTRACT adds quotes around its result resulting in "PRO" instead of PRO and therefore the IFNULL default is not triggered and the subscription plan, which is PRO, is not found using "PRO".
Add JSON_UNQUOTE around the JSON_EXTRACT solves the issue.

Concatenate only when all values are true in mysql

The following is the query I have used to concatenate siretagprefix and siretagsec
CONCAT('TZN',
`adggtnz`.`reg04_rpt_animreg`.`siretagprefix`,
`adggtnz`.`reg04_rpt_animreg`.`siretagsec`) AS `siretagid`,
The result of the query when siretagprefix and siretagsec when the values are null, I get TZN as the result. How can I concatenate only when all the values are true.
You could use CASE to check your column values
CASE WHEN `adggtnz`.`reg04_rpt_animreg`.`siretagprefix` IS NOT NULL
AND `adggtnz`.`reg04_rpt_animreg`.`siretagsec` IS NOT NULL
THEN
CONCAT('TZN',
`adggtnz`.`reg04_rpt_animreg`.`siretagprefix`,
`adggtnz`.`reg04_rpt_animreg`.`siretagsec`)
ELSE NULL END AS siretagid
You could use a case expression:
CASE WHEN `adggtnz`.`reg04_rpt_animreg`.`siretagprefix` IS NOT NULL AND
`adggtnz`.`reg04_rpt_animreg`.`siretagsec` IS NOT NULL
THEN CONCAT('TZN',
`adggtnz`.`reg04_rpt_animreg`.`siretagprefix`,
`adggtnz`.`reg04_rpt_animreg`.`siretagsec`)
END AS `siretagid`

Issue with NULL value in nested case

Long story short i need to return a varchar value if stored value is null but eithers bring me a NULL value or varchar value here is the code.
in the table i have some fields null and some with data
CASE WHEN DS.DBIRTH+DS.MBIRTH+DS.YBIRTH =
'' THEN CONVERT(VARCHAR(10),PT.CLIENTDBIRTHDATE,111)
ELSE 'INPUT DATE OF BIRTH'
CASE WHEN PT.CLIENTBIRTHDATE IS NULL THEN ''
ELSE '1800-01-01'
END
END AS BFIELD
this brings me something like this
NULL
1917/05/02
NULL
1923/02/02
1967/01/05
NULL
but i need something like this
01/01/1800
1917/05/02
01/01/1800
1923/02/02
1967/01/05
01/01/1800
sorry for the ultra noob question
Your current case statement looks off. I imagine what you want to do is wrap the result in coalesce:
COALESCE(CASE
WHEN DS.DBIRTH+DS.MBIRTH+DS.YBIRTH = ''
THEN CONVERT(VARCHAR(10),PT.CLIENTDBIRTHDATE,111)
ELSE 'INPUT DATE OF BIRTH'
END, '01/01/1800') AS BFIELD
Without the Case statement it should be something as simple as....
select CONVERT(VARCHAR(10) ,
CAST(ISNULL(DateColumn,'01/01/1800') AS DATE)
,111)

Skipping AND when variable IS NULL

I have an existing Stored Procedure and i add some parameter to filter the result.But when #id_account is null it returns Empty Data. I want to skip AND when #id_account is null, i try IF condition but it wont work. Any suggestion? Thanks :D
AND
(
pd_account.id_account = #id_account
)
Put in the condition you really want, which is:
(pd_account.id_account = #id_account or #id_account is null)
Use:
AND
(
pd_account.id_account = COALESCE(#id_account,pd_account.id_account)
)
From COALESCE doc
Returns the first non-NULL value in the list, or NULL if there are no
non-NULL values.
So when #id_account is not provided the condition will be pd_account.id_account =pd_account.id_account which is equivalent to 1=1 always true.
You can use CASE like:
AND pd_account.id_account = CASE WHEN #id_account IS NOT NULL THEN #id_account
ELSE pd_account.id_account
END

NULL != NULL in mysql query

I am trying to do a query that sees if fields are equivalent. However, whenever the field is NULL it returns a false result. I even tried doing the same thing with the column itself:
SELECT * FROM `mturk_completion` WHERE (`mturk_completion`.`imdb_url` =
`mturk_completion`.`imdb_url` AND `mturk_completion`.`worker_id` = 'A3NF84Q37D7F35' )
And it only returns results where the column is not NULL. Why is this so, and how do I get around it?
Your title is absolutely correct for any SQL implementation (not just MySQL). NULL is not equal to anything (including another NULL).
You need to use explicit IS NULL check or COALESCE() function (or its RDBMS-dependent alternatives) to set some default value in case of NULL.
Your comparison of mturk_completion.imdb_url to itself is redundant and should always return True, except when mturk_completion.imdb_urlis Null, in which case it will return Null.
That's because the operator = returns either True, False when comparisons can be made or Null, when either of the two operators is Null
Try this to illustrate the situation.
SELECT 1 = NULL; -- returns NULL
SELECT 1 != NULL; -- also return NULL
SELECT ISNULL(1 = NULL); -- returns 1
SELECT ISNULL(1 != NULL); -- returns 1
If you rewrite your query like below, your problems with ignoring NULLs will go away:
SELECT * FROM `mturk_completion` WHERE worker_id = 'A3NF84Q37D7F35'
I think you can use
(table.Field = table2.Field OR COALESCE(table.Field, table2.Field) IS NULL)