MySQL avoiding null values for sum operations? - mysql

I need to make a column that counts the amount of variables which are above 0, and that won't return null if there is any non-null value in it, for each value in an id column.
What I managed to make is using a sum between some boolean operations:
IF 'A' THEN 'B' ELSE 'C' (at least that's what I've got)
select ID, `jul`, `aug`, `set`, `oct`, `nov`, `dec`,
((((not `jul`) or 1) and (`jul` or 0))
+(((not `aug`) or 1) and (`aug` or 0))
+(((not `set`) or 1) and (`set` or 0))
+(((not `out`) or 1) and (`out` or 0))
+(((not `nov`) or 1) and (`nov` or 0))
+(((not `dec`) or 1) and (`dec` or 0))) as sum from table;
It works at first view, but if there is any null value in a line, the sum returns null for each respective id.
What could I do to avoid this problem?

try
SUM( IFNULL(jul,0)+IFNULL(ago,2) ) as sum from table
/*
obs: the SUM is good to sum multiple values
IFNULL returns 0 to the sum if jul is null and 2 for ago if ago is null in the example.
*/
i think it works. :)

You need to use a coalesce or variant to deal with nulls. Null value represents an unknown. You can't add unknowns and get something other than an unknown.
NULL + 1 = NULL
COALESCE(NULL, 0) + 1 = 1

Use isnull(columnname, 0) to turn nulls into 0s. So isnull('jul',0)+isnull('aug',0) etc.

Related

MySQL query to return 1 and 0 based on difference between dates

In MySQL Database I have a table ABC that consists of a column 'LastDate'.
LastDate which has datatype as DATETIME. The default value for this 'NULL'
I need to write a query for the table which would
Return '1' in these cases.
1) If DATEDIFF(CURRENT_TIME,LastDate) is >15 or if DATEDIFF(CURRENT_TIME,LastDate) is
NULL(i.e defaultVal).
return '0' if DATEDIFF(CURRENT_TIME,LastDate) is <15.
I tried to write an SQL query for this but was unable to do it. Please help me write this Query. Thanks in advance.
You can be explicit about your logic:
select t.*,
(case when DATEDIFF(CURRENT_TIME, LastDate) > 15 or
LastDate is null
then 1 else 0
end) as flag
from t;
This can be simplified to:
select t.*,
coalesce(DATEDIFF(CURRENT_TIME, LastDate) <= 15, 1) as flag
from t;

Subtract values from sum depending on the value of another column

I have a mysql table with columns:
value - integer
type - integer
value only can be positive integer, type can be 0 or 1
I need to sum this value, but the thing is that if type value is 1 i need to subtract this row value from my sum.
Is its possible to make without two queries?
You can try something like this, using if:
sum( if(`type` = 1, -1, 1) * `value` )
Or case:
sum( (case when `type` = 1 then -1 else 1 end) * `value` )

Query - To display the Failure rate %

I have written this query to get my data, and all the data is fine.
I have one column which has either Pass Or Fail. I want to calculate the % of number of bookings that failed, and output it in a single value.
I will have to write another query to show that one number.
For example : The below data, I have 4 bookings , out which 2 failed. So 50% is the failure rate. I am omitting some columns , in the display, but can be seen in the query.
That's an aggregation over all records and simple math:
select count(case when decision = 'Fail' then 1 end) / count(*) * 100
from (<your query here>) results;
Explanation: COUNT(something) counts non null values. case when decision = 'Fail' then 1 end is 1 (i.e. not null) for failures and null otherwise (as null is the default for no match in CASE/WHEN &dash; you could as well write else null end explicitly).
Modify your original condition to the following. Notice that there is no need to wrap your query in a subquery.
CONCAT(FORMAT((100 * SUM(CASE WHEN trip_rating.rating <= 3 AND
(TIMESTAMPDIFF(MINUTE,booking.pick_up_time,booking_activity.activity_time) -
ROUND(booking_tracking_detail.google_adjusted_duration_driver_coming/60)) /
TIMESTAMPDIFF(MINUTE,booking.pick_up_time,booking_activity.activity_time)*100 >= 15
THEN 1
ELSE 0
END) / COUNT(*)), 2), '%') AS failureRate
This will also format your failure rate in the format 50.0%, with a percentage sign.

Counting Records in a Form

Ok we know that Count will not count null values. So ...
qty_rec is a numeric field.
=Count(Nz([qty_rec],0)<1)
This is what I have for my Control Source on a textbox.
It returns the total number of records rather than the 5 that are null or zero.
What I need is a count of items that do not have a received quantity or a zero quantity.
If your goal is to count the number of records where qty_rec is Null, consider Sum of an IIf expression.
=Sum(IIf(IsNull([qty_rec]), 1, 0))
If the goal is actually count of zero or Null, use this instead:
=Sum(IIf(Nz([qty_rec], 0) = 0, 1, 0))
If you prefer Count instead of Sum, this should give you the same result as the second example:
=Count(IIf(Nz([qty_rec], 0) = 0, 1, Null))

MySQL if then clause

I sum up the rows of two columns in two tables i.e. something like this:
SUM( tableA.age ) + sum( tableB.age) as 'Total Ages'
But in some cases the result of table A is null while result of table B is not. In this case I get as a total result null although it is something like "NULL + 45" which is not null actually. Therefore I thought it would be a good idea to use the if clause of the sql syntax. But it does not work I get an error when trying to do the following:
IF SUM( tableA.age ) IS NULL THEN 0 ELSE SUM( tableA.age ) END IF + IF SUM( tableB.age ) IS NULL THEN 0 ELSE SUM( tableB.age ) END IF
How would I do that in a proper way?
Simply use IFNULL() when you feel the field has NULL value.
SUM(IFNULL(tableA.age,0) )
You can use this MYSQL function.
Instead of the complex (and syntactically incorrect) IF statements, use COALESCE(), which returns its first non-null argument, and specify 0 as its second argument so it defaults to zero when the aggregate SUM() is null
COALESCE(SUM(tableA.age), 0) + COALESCE(SUM(tableB.age), 0)
Use IFNULL(column, 0) to convert the column value to zero:
SUM( IFNULL(tableA.age,0) ) + SUM( IFNULL(tableB.age,0) ) as 'Total Ages'