Average without calculate zero - sql

I have some fields in the table, need to average those fields.
Then I run this syntax, because I don't want to calculate 0 (zero) value.
SELECT myDate, AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01'
On my syntax, the average calculation means.. Make zero value to null.
My question is, How if all values are zero...?
Thank you.

Then you get NULL.
If you want zero instead, use COALESCE:
COALESCE( AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) , 0)

Average will not use nullvalues to calculate an average value
IsNull or Coalesce can be used to change null values to different values.
This script will change 0 to null and take the average value:
SELECT IsNull(AVG(NullIf(val,0)), 0)
FROM
(Values(5),(7),(0)) tbl(val)
Since 0 is excluded the result is 6

You could also do this:
SELECT myDate, COALESCE(AVG(myField1), 0) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01' and myField1 <> 0

Related

Multiple conditions in select statement based on values

I have a multiple ctes. In my select statement I must filter values base on the conditions. This is my query.
SELECT roadName
,sum(roadLength) AS sumRoadLength
,avg(elevationDifference) AS eglAvgDepth
,avg(elevationDifference) AS pglAvgDepth
,
FROM cte3
GROUP BY roadName
ORDER BY roadName
Under "elevationDifference" there are lots of values ranging from -10 to +20 which are spread through "roadName". What i want to accomplished is that "eglAvgDepth" will return if all "elevationDifference" values are <0 and take the average. Same case with pglAvgDepth where values are >0.
I tried to add where statement but works only in eglAvgDepth
WHERE elevationDifference < 0
GROUP BY roadName
ORDER BY roadName
Just add a conditional expression:
avg(case when elevationDifference < 0 then elevationDifference end) as eglAvgDepth,
avg(case when elevationDifference > 0 then elevationDifference end) as pglAvgDepth,
EDIT:
You have phrased this that you want the value based on whether all the values are positive or negative. If so:
(case when max(elevationDifference) < 0 then avg(elevationDifference) end) as eglAvgDepth,
(case when max(elevationDifference) > 0 then avg(elevationDifference) end) as pglAvgDepth,

Using SUM SEC_TO_TIME in MariaDB

Reference from How to sum time using mysql
I want to SUM Field LogsFormatted.Late Every month with query :
SELECT
SUM(CASE
WHEN MONTH (LogsFormatted.DateIn) = 1
THEN SEC_TO_TIME( SUM( TIME_TO_SEC(LogsFormatted.Late)))
ELSE 0 END
) AS '1'
FROM
HrAttLogsFormatted AS LogsFormatted
But the result is
1111 - Invalid use of group function
Where is the problem with the query? resulting in an error output.. Thank you in advance
[EDIT-SOLVED] It's Solved with simply apply
Change format SUM at the beginning of the query
SEC_TO_TIME(SUM(
CASE WHEN MONTH(LogsFormatted.DateIn) = 1 THEN
TIME_TO_SEC(LogsFormatted.Late) END)
) AS '1'
You don't need to call the sum() so many times. You can also move the case condition to the WHERE clause:
SELECT SUM(TIME_TO_SEC(lf.Late))
FROM HrAttLogsFormatted lf
WHERE MONTH(lf.DateIn) = 1 ;
If you want conditional aggregation, then do:
SELECT SUM(CASE WHEN MONTH(lf.DateIn) = 1 THEN TIME_TO_SEC(lf.Late) END)
FROM HrAttLogsFormatted lf;

How to write a sql query if order time is greater then 24:00:00 than 1 otherwise 0?

Order Time
00:36:06
02:21:59
04:53:57
05:52:38
00:29:11
17:53:29
00:17:03
02:03:20
01:24:02
00:09:43
00:20:55
02:53:30
00:32:26
07:45:31
09:11:37
00:19:17
92:11:21
00:19:08
00:10:50
02:46:05
How to write a sql query if order time is greater then 24:00:00 than 1 otherwise 0?
Presumably, ordertime is a string. You can do this as:
select (case when ordertime > '24:00:00' then 1 else 0 end)
Assuming that in some magic way you were able to insert 92:11:21 into a time column, use this calculated column in your query:
CASE WHEN DATEDIFF(second, 0, [Order Time]) > 86400
THEN 1
ELSE 0
END AS GreaterThan24h

TSQL Counting with Nulls

I have a table what counts admited and discharge from ED. This is what the table looks like
I'm trying to get the total admitted and discharged. Something like
Admitted - 100
Discharge - 200
Is there a way to do that with the NULL values?
select
sum(case when Admitted is null then 0 else Admitted end) Admitted,
sum(case when DischargedFromED is null then 0 else DischargedFromED end) as DischargedFromED
from MyMagicalTable;
or
select
sum(coalesce(Admitted, 0)) Admitted,
sum(coalesce(DischargedFromED, 0)) DischargedFromED
from MyMagicalTable;
Just use sum();
select sum(admitted) as admitted, sum(DischargedFromED) as DischargedFromED
from t;
Aggregation functions ignore NULL values.
If you are concerned about NULL values appearing after the sum(), then use coalesce() afterwards:
select coalesce(sum(admitted), 0) as admitted,
coalesce(sum(DischargedFromED), 0) as DischargedFromED
from t;
The above assumes that the columns are numeric. If they are some other type, they need to be converted to numbers.

Remove negative values

I have a certain query that obtains derived values
select datediff(minute, date_field_1, date_field_2) as date_diff from table_name;
The problem is that some of the values in the result can be negative as date_field_1 can be greater than date_field_2 in some cases.
So this results in negative, along with positive values in the resultant table.
Is there anyway to put some default values or omit and give null or zero in those negative calculated values ?
Using redshift.
One way to catch negative values would be to use CASE WHEN. It checks whether your datediff is smaller than 0.
I proposed 0 as default value:
SELECT
CASE WHEN datediff(minute, date_field_1, date_field_2) < 0
THEN 0
ELSE datediff(minute, date_field_1, date_field_2) END as date_diff
FROM table_name;
Is this what you want?
select (case when date_field_1 >= date_field_2
then datediff(minute, date_field_1, date_field_2)
else 0
end) as date_diff
from table_name;