Unintended behavior: Subtraction between null values results in '0' - mysql

When either one of the field is NULL, I want the returned value to be NULL as well. I have also tried reversing the logic: is not null. Still the same results.
MySQL code:
(case
when
((`creative_stg_sample_tracking_raw`.`total_samples_received` is not null)
and (`creative_stg_sample_tracking_raw`.`total_samples_forecasted` is not null))
then
(cast(`creative_stg_sample_tracking_raw`.`total_samples_received`
as signed) - cast(`creative_stg_sample_tracking_raw`.`total_samples_forecasted`
as signed))
else NULL
end) AS `received_forecasted_dif`
Screenshot:

Your code should be working, but you don't need the case. Whenever one of the values is NULL, the expression should be NULL:
(cast(`creative_stg_sample_tracking_raw`.`total_samples_received` as signed) -
cast(`creative_stg_sample_tracking_raw`.`total_samples_forecasted` as signed))
) AS `received_forecasted_dif`
I wonder if your problem is that the value is actually 'NULL' rather than NULL. That is, a string value rather than a real NULL. MySQL will treat the string as 0 in the arithmetic.
You can fix this by doing:
(case when `creative_stg_sample_tracking_raw`.`total_samples_received` <> 'NULL' and
`creative_stg_sample_tracking_raw`.`total_samples_forecasted` <> 'NULL'
then (cast(`creative_stg_sample_tracking_raw`.`total_samples_received` as signed) -
cast(`creative_stg_sample_tracking_raw`.`total_samples_forecasted` as signed))
)
else NULL
end) AS `received_forecasted_dif`

Related

SQL EXTRACT returns HOUR_MINUTE without colon

I am trying to format my timestamp date to get only hour with minutes from it. The problem is that the returned format is weird "825-2100" when it should be "8:25-21:00". So the output should be with colon but it is without.
This is the select I am doing:
CASE WHEN (TRUE) then CONCAT('Aeg ',EXTRACT(HOUR_MINUTE FROM fp.valid_from), '-', EXTRACT(HOUR_MINUTE FROM fp.valid_to) else 0 end,
Why I get format without colon?
Use format if you want a string. Also, all branches of the CASE should return a string (or NULL):
(CASE WHEN (TRUE)
THEN CONCAT('Aeg ',
FORMAT(fp.valid_from, '%H:%i%'),
'-'
FORMAT(fp.valid_to, '%H:%i%')
)
ELSE ''
END)

how to send "" instead of null in select * statement SQL

SELECT * FROM specifications
I want to send "" or "0" instead of null[if any column having null value],
can't use column-wise, more than 80 columns
As mentioned in the comments, the only way is to use COALESCE() OR ISNULL() as many times as the count (80) of your columns.
Just to make it easier, you can use the below query to generate that 80 statements for you.
SELECT CONCAT('ISNULL(',COLUMN_NAME ,',' ,
(CASE WHEN DATA_TYPE ='int' THEN '0'
WHEN DATA_TYPE ='varchar' THEN '' ELSE '' END) , ')' )
AS DERIVED_COLUMN
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'specifications'
CHECK SAMPLE DEMO HERE
Note : This is under the assumption that all your column are of int or varchar datatype. If you have other datatypes, modify the CASE accordingly.

Where clause in SQL Query skip date filter when date is null

I have search query with parameters are Name, From date, To date. When i pass empty string or null to date parameters it should return all data matches with name only. This code is not working for me.
WHERE name=#name
AND
(CASE WHEN #_from IS not null
THEN
Servicedate<=#_from
END)
This is also not woking for me.
WHERE name = #name AND
Servicedate>=ISNULL((case when #_from='' then NULL else #_from),Servicedate)
Thank You.
You can use this:
WHERE
name = #name
AND (#_from IS NULL OR ServiceDate >= #_from)
AND (#_to IS NULL OR ServiceDate <= #_to)
If the variables(#_from and #_to) are unset, the condition will return true since #var IS NULL is true.
WHERE ( name=#name AND #_from IS NOT NULL AND Servicedate<=#_from )
OR
( name=#name AND #_from IS null )
If date parameter #_from is empty then searching is done only on name parameter #name else ServiceDate column is matched against date parameter #_from
WHERE
(name=#name AND #_from IS NOT NULL AND #_from <> '' AND Servicedate<=#_from )
OR
(name=#name AND (#_from IS null or #_from = ''))

Using a field of view in the view's sub query

I have a view which has a column which is calculated from other columns. For example, in my original table I have the columns A and B from which I calculate the value of column X in my view. I need the value of X in another column I have in the view - Z. But when I put it in the sub-query of my view I get an Unknown column 'X' in 'field list' SQL statement.
The sub-query of the view looks like this:
(CASE
WHEN (`users`.`A` REGEXP '^(regexone)') THEN 'ValueA'
WHEN (`users`.`B` REGEXP '^(regextwo)') THEN 'ValueB'
ELSE ''
END) AS `X`,
(CASE
WHEN
(`X` = 'ValueA')
THEN
(`users`.`C`*0.95-0.3)
ELSE ''
END) AS 'Z'
What's the correct syntax of using a computed view field in the computation of another field?
if you can you user-defined variables use like
SELECT
#x := (CASE
WHEN (`users`.`A` REGEXP '^(regexone)') THEN 'ValueA'
WHEN (`users`.`B` REGEXP '^(regextwo)') THEN 'ValueB'
ELSE ''
END) AS `X`,
(CASE
WHEN
(#x = 'ValueA')
THEN
(`users`.`C`*0.95-0.3)
ELSE ''
END) AS 'Z'

MYSQL - Truncated incorrect DOUBLE value: '-'

This UPDATE fails with the error "Truncated incorrect DOUBLE value: '-'" and I cannot figure out why.
UPDATE psych
SET pdqp_adm=CAST((CAST(pdqt_adm AS SIGNED)) - (CAST(pdqf_adm AS SIGNED)) AS CHAR)
WHERE pdqt_adm>0
AND pdqt_adm IS NOT NULL
AND pdqf_adm>0
AND pdqf_adm IS NOT NULL
AND pdqt_adm>=pdqf_adm
All of the columns used here (pdqp_adm, pdqt_adm, pdqf_adm) are VARCHAR(6). I can do this query and the calculation works just fine:
SELECT CAST((CAST(pdqt_adm AS SIGNED)) - (CAST(pdqf_adm AS SIGNED)) AS CHAR)
FROM psych
WHERE pdqt_adm>0
AND pdqt_adm IS NOT NULL
AND pdqf_adm>0
AND pdqf_adm IS NOT NULL
AND pdqt_adm>=pdqf_adm
Ok, this error had nothing to do with the calculated values.
When I run this, I get this same error (only for record with ID 4972):
SELECT p.id, p.pdqt_adm, p.pdqf_adm
FROM psych p
WHERE p.pdqt_adm>0
AND p.pdqt_adm IS NOT NULL
AND p.pdqf_adm>0
AND p.pdqf_adm IS NOT NULL
AND p.id=4972
As it turns out, the 2 columns being used to compare to 0 and to each other both contain the value "-". Now, why this does not affect my SELECT in my question above, but does affect my UPDATE...I have no idea.
The update and select do not necessarily process the table in the same order. You can try:
UPDATE psych
SET pdqp_adm=CAST((CAST(pdqt_adm AS SIGNED)) - (CAST(pdqf_adm AS SIGNED)) AS CHAR)
WHERE (case when pdqt_adm <> '-' then pdqt_adm else 0 end) > 0 AND
pdqt_adm IS NOT NULL AND
(case when pdqf_adm <> '-' then pdqf_adm else 0 end) > 0 AND
pdqf_adm IS NOT NULL AND
(case when pdqt_adm <> '-' then pdqt_adm else 0 end) >= (case when pdqf_adm <> '-' then pdqf_adm else 0 end);