This question already has answers here:
MySQL AVG() return 0 if NULL
(3 answers)
Closed last month.
I have the following structre
id val
1 ...
.
.
2 ...
.
.
3 null
3 null
3 null
4 ...
.
.
Basically each id has multiple no. of values. And an id has either all values as integers or all values as null
What I want is to perform an aggregate (like AVG) on val group by id. If that id has null values, I want to put 5 there.
#1
SELECT id, (CASE SUM(val) WHEN null THEN 5 ELSE AVG(val) END) AS ac FROM tt GROUP BY id
> executes ELSE even for id = 3
In CASE, there should be an aggregate function that when done on null values give null.
I checked SUM and MAX like
SELECT SUM(val) FROM tt WHERE id = 3
> null
and it gives null here but doesn't work in main statement. I guess it is related to the type of equality and hence tried WHEN IS NULL but its a syntax error.
Also, is there some more standard way of indicating group of values as all null rather than using SUM or MAX.
You can use if condition :
select id, If(sum(val) is null, 5, AVG(val)) as average
FROM tt
group by id
check here : https://dbfiddle.uk/Uso9nNTM
The exact problem with your CASE expression is that to check for null in MySQL we have to use IS NULL rather than equality. So use this version:
CASE WHEN SUM(val) IS NULL THEN 5 ELSE AVG(val) END
But we might as well just use COALESCE() to assign an average of 5 for those id groups having all null values.
SELECT id, COALESCE(AVG(val), 5) AS avg_val
FROM tt
GROUP BY id;
Note that the AVG() function by default ignores nulls. Therefore, the expression AVG(val) would only be null if every record in an id group were having null for val.
Related
I have a simple column with some numbers, which looks like;
133
8
55
11
NULL
NULL
235
NULL
I want to put a default in when selecting this column, with the aim of replacing the nulls. I've done;
CASE
WHEN round(avg(s.seconds)) IS NULL THEN 0
ELSE round(avg(s.seconds))
END as 'seconds'
However, my nulls remain. My expectation is that they would be set to 0. Why would this not work?
NULL values are ignored in average calculations.
If you want to replace NULL values for 0 in your average, you need to use COALESCE on the values, inside the average function. Example follows:
DROP TEMPORARY TABLE IF EXISTS TEMP1;
CREATE TEMPORARY TABLE TEMP1
SELECT 1 AS price
UNION ALL SELECT NULL AS price
UNION ALL SELECT NULL AS price
UNION ALL SELECT 3 AS price;
SELECT * FROM TEMP1; # List values (1, NULL, NULL, 3)
SELECT AVG(price) FROM TEMP1; # Returns 2 (NULL values IGNORED)
SELECT AVG(COALESCE(price,0)) FROM TEMP1; # Returns 1 (NULL values REPLACED with 0)
You can do it by 3 ways
1
round(avg(CASE
WHEN s.seconds IS NULL THEN 0
ELSE s.seconds
END)) as 'seconds'
2
The MySQL IFNULL() function lets you return an alternative value if an
expression is NULL:
round(avg(IFNULL(s.seconds,0)))
3
or we can use the COALESCE() function, like this:
round(avg(COALESCE(s.seconds,0)))
I want count the length of a comma separated column
I have use these
(LENGTH(Col2) - LENGTH(REPLACE(Col2,",","")) + 1)
in my select query.
Demo:
id | mycolumn
1 2,5,8,60
2 4,5,1
3 5,Null,Null
query result for first two row is coming correctly.for 1 = 4 ,2 = 3 but for 3rd row it is calculating null value also.
Here is what I believe the actual state of your data is:
id | mycolumn
1 2,5,8,60
2 4,5,1
3 NULL
In other words, the entire value for mycolumn in your third record is NULL, likely from doing an operation involving a NULL value. If you actually had the text NULL your current query should still work.
The way to get around this would be to use COALESCE(val, "") when handling the NULL values in your strings.
Crude way of doing it is to replace the occurances of ',Null' with nothing first:-
SELECT a.id, (LENGTH(REPLACE(mycolumn, ',Null', '')) - LENGTH(REPLACE(REPLACE(mycolumn, ',Null', ''),",","")) + 1)
FROM some_table a
If the values refer to the id of rows in another table then you can join against that table using FIND_IN_SET and then count the matches (assuming that the string 'Null' is not an id on that other table)
SELECT a.id, COUNT(b.id)
FROM some_table a
INNER JOIN id_list_table b
ON FIND_IN_SET(b.id, a.mycolumn)
GROUP BY a.id
I have trouble wondering how do I count distinct value. using if on the select column
I have SQLFIDDLE here
http://sqlfiddle.com/#!2/6bfb9/3
Records shows:
create table team_record (
id tinyint,
project_id int,
position varchar(45)
);
insert into team_record values
(1,1, 'Junior1'),
(2,1, 'Junior1'),
(3,1, 'Junior2'),
(4,1, 'Junior3'),
(5,1, 'Senior1'),
(6,1, 'Senior1'),
(8,1, 'Senior2'),
(9,1, 'Senior2'),
(10,1,'Senior3'),
(11,1, 'Senior3'),
(12,1, 'Senior3')
I need to count all distinct value, between Junior and Senior column.
all same value would count as 1.
I need to see result something like this.
PROJECT_ID SENIOR_TOTAL JUNIOR_TOTAL
1 3 3
mysql query is this. but this is not a query to get the result above.
SELECT
`team_record`.`project_id`,
`position`,
SUM(IF(position LIKE 'Senior%',
1,
0)) AS `Senior_Total`,
SUM(IF(position LIKE 'Junior%',
1,
0)) AS `Junior_Total`
FROM
(`team_record`)
WHERE
project_id = '1'
GROUP BY `team_record`.`project_id`
maybe you could help me fix my query above to get the result I need.
thanks
I think you want this:
SELECT
project_id,
COUNT(DISTINCT CASE when position LIKE 'Senior%' THEN position END) Senior_Total,
COUNT(DISTINCT CASE when position LIKE 'Junior%' THEN position END) Junior_Total
FROM team_record
WHERE project_id = 1
GROUP BY project_id
The CASE will return a null if the WHEN is false (ie ELSE NULL is the default, which I omitted for brevity), and nulls aren't counted in DISTINCT.
Also, unnecessary back ticks, brackets and qualification removed.
I have simple table (test) where I need to perform some additions (I want to get a row total and a column total).
id var1 var2
1 NULL NULL
2 10 NULL
For column totals, summing works as expected (NULL is ignored in the addition):
SELECT SUM(var1) FROM test
10
For row totals, addition does not ignore NULL (if any column is NULL the result is NULL):
SELECT var1+var2 FROM test
NULL
NULL
What I want it to return is:
SELECT var1+var2 FROM test
NULL
10
Is there a way to get MySQL to treat NULL as 0 in an addition?
You want to use coalesce():
select coalesce(var1, 0) + coalesce(var2, 0)
coalesce() is ANSI standard and available in most databases (including MySQL).
use the IFNULL function
SELECT IFNULL(var1, 0) + IFNULL(var2, 0) FROM test
select
Case when (coalesce(`var1`, 0) + coalesce(`var2`, 0))=0
then NULL
else coalesce(`var1`, 0) + coalesce(`var2`, 0)
end
from test
SQL FIDDLE
Well, the values aren't null per say, they are in VARCHAR(30) but in decimal form. However some of the records have "NA" in some fields. I would like mysql to skip those rows in SUM calculation when "NA" is present in the fields used for the SUM. Mysql is treating all incalculable fields as 0. The 0 from fields containing "NA" is misleading. I am doing a GROUP BY TABLE.ID.
Edit:
SELECT
SUM(
CASE
WHEN X >1 THEN 1
WHEN X<-1 THEN 2
ELSE 3
END
CASE
WHEN Y >1 THEN 1
WHEN Y <-1 THEN 2
ELSE 3
END)
AS "Col X+Y";
FROM TableA
GROUP BY TableA_ID;
Sometimes X and/or Y = "NA" on certain fields. I get 6 if both X and Y on TableA_ID = 17 or other numbers when one of them is "NA".
Edit (quoting my comment on VARCHAR):
"I tried storing my values as DEC(5,2), but some of the data from Excel have NA's in the fields. I did set X DEC(5,2) NULL and tried inserting NA into it but kept getting an error (cannot be null). I also tried making the default value "NA" but still get an error (cannot be null). I'll add in a sample query as edit."
I got it. I added in another WHERE clause using
WHERE ..... AND(Colx IS NOT NULL OR Coly IS NOT NULL OR ......);
I switched back the values to DEC(3,1) and made the fields NULLable with defaults null if the field value is NULL. I had to understand how to use NULL. I took out the 'NA's in Excel and left those field values blank.
if foo1 is null or NA just sum it as zero (the neutrum value in the addition), otherwise sum the value.
select sum( case when foo1 is null or foo1 = 'NA' then 0 else foo1 end) as sum, foo2
from FooTable group by foo2
or
select sum(foo1) from FooTable
where (foo2 <> 'NA' and foo2 is null) and (foo3 <> 'NA' or foo3 is null )
group by foo4