5, Not sure what am I doing wrong, please help. As it seems in a query on multiple column comparison to find least value,
NULL continues to show up as a Resultant instead of least value
SELECT
IF(col1 IS NULL OR col2 IS NULL OR col3 IS NULL OR col4 IS NULL OR col5 IS NULL,
COALESCE(col1,col2,col3,col4,col5),
LEAST(col1,col2,col3,col4,col5)
) As Resultant
from db.tablename
Group by Id;
Alternatively tried CASE select without much success.
Thanks
if null is considered 0
select least(ifnull(col1,0),ifnull(col2,0),ifnull(col3,0),ifnull(col4,0),ifnull(col5,0))
as Resultant
from db.tablename
Group by Id;
if null is condered max
select least(ifnull(col1,~0>>1),ifnull(col2,~0>>1),ifnull(col3,~0>>1),ifnull(col4,~0>>1),ifnull(col5,~0>>1))
as Resultant
from db.tablename
Group by Id;
For people with the case such that there are only two values to compare, you can do this:
GREATEST(ifnull(a,b), ifnull(b,a))
Related
How to sum two or three columns, but if any column is NULL then it should not affect the value of SUM.
As i get NULL if columns are added all together.
Here is the example of table i am trying to work on.
id col1 col2 col3 total
1 2 3 5
2 10 5 NULL
3 2 NULL NULL
This is the query i tried.
SELECT id,col1,col2,col3, (col1+col2+col3) AS Total FROM test_table;
This Query works perfectly fine if there is no NULL column, but if there is any null column then number added with null becomes null and i get null in result..
Below is the Result Screen Shot i added.
in above image i get NULL in Total column if any column in sum has null.
But results should be like 10,15,2 respected to there id's.
One way would be to use IFNULL function:
SELECT id,col1,col2,col3, (IFNULL(col1,0)+IFNULL(col2,0)+IFNULL(col3,0)) AS Total
FROM test_table;
Use coalesce to replace null values with 0. I prefer coalesce. In my experience it is database agnostic, where as isnull, ifnull, nvl and others are specific to the database.
SELECT col1,col2,col3, (coalesce(col1,0)+ coalesce(col2,0)+ coalesce(col3,0)) as total from test_table;
In this case you would need to use IsNull(Column, 0) to ensure it is always 0 at minimum.
SELECT col1, col2, col3, sum(isnull(col1,0) + isnull(col2,0) + isnull(col3,0)) AS Total FROM test_table group by id;
Modify your select statement to exclude nulls.
money
20.00
17.87
5.00
NULL
3.00
I want the null entries turned into zeroes. The money column is for money spent. Ive tried the following and it didnt like changing NUll to a dollar value.
select case money when 'NULL' then 0 end
from mytable
select coalesce(money, 0) from mytable
Coalesce will take the first non-null value in the list.
Try:
SELECT IsNull(money, 0)
FROM mytable
EDIT
If you want to replace the values in the table:
UPDATE mytable
SET money = 0
WHERE money Is Null
While I agree with the other two answers, I wasnted to explain why what you did was not right.
select case money when 'NULL' then 0 end
from mytable
Here you are treating NULL as a string value. But NULL is a condition not a value. It means there is no known value. If you inserted the actual word 'null' into the table in that field, then your code would have worked.
When you want to test for a NULL condition you use:
WHERE field1 IS NULL
or you change the value using coalesce or ISNULL. If you need to test for NULL as part of a case statement, then you would do it like this:
CASE WHEN field1 IS NULL THEN 0 ELSE T1 END
For simple cases like yours, COALESCE or ISNULL is best. But at times you may need to do a very complicated CASE and then it is handy to know how to do it.
I am able to replicate my issue with a very simple case..
Explanation
I have a very simple table my_table with one column column1.
create table my_table (column1 varchar(58));
I have few values for this column, NULL is also one of them.
insert into my_table (column1) values ('value1'), ('value1'), ('value2'), (null), ('value2');
Problem
When I try to query for group by column1 It is giving expected results by grouping all NULLs together. However if I add a where clause on column1 something like
select count(1) as value_count, column1 from my_table where column1 <> 'value1' group by column1;
It is ignoring both value1 and NULL where I was expecting to ignore only value1.
With this simple case I could get a workaround for this by adding an OR condition, But it is a real pain to add this condition all over in my original case.
Could someone can explain me better why this behavior and how can I fix this?
This is because any comparison with a NULL does not produce a true or false result, but instead produces a NULL result. Consequently, the condition column1 <> 'value1' evaluates as NULL where column1 is NULL, and so NULL values are not selected.
You can get around this by using a function such as coalesce to test column1 - like so:
select count(1) as value_count, column1
from my_table
where coalesce(column1,'') <> 'value1'
group by column1;
Null means "a value, but I don't know what it is".
So is column1 <> 'value1'? If column1 is null, then "Is a value, but I don't know what it is, unequal to 'value1'"?
Clearly the answer is "I don't know. I don't know what the value is".
The only rows included by a where clause are those which pass the where clause test. We don't know if this row passes the test, so it will not be included in the query.
You could try making use of the MySQL IFNULL in your predicate:
select count(1) as value_count, column1 from my_table where ifnull(column1,'nullvalue') <> 'value1' group by column1;
I found this question ( How to get the max of two values in MySQL? ) while looking for ways to compare discrete set of values.
I want to be able to get the minimum of few selected values where some of them may be null because they are optional but the MySQL docs says:
If any argument is NULL, the result is NULL.
Use a COALESCE() function on the nullable values:
select LEAST(COALESCE(#foo, <max int>), COALESCE(#bar, <max int>));
if you get the max int value, then both were null (unless there's a decent chance you could actually have the max int value as a real argument, then more logic is necessary)
How about this:
LEAST(COALESCE(col1, col2, col3),
COALESCE(col2, col3, col1),
COALESCE(col3, col1, col2))
Obviously this doesn't scale well to more than 3 values.
Works, is easily extendible, and doesn't rely on any values not being found in the data but probably heinously inefficient!
CREATE TABLE X
(
Id int primary key,
col1 int null,
col2 int null,
col3 int null
)
Query
SELECT id,
Min(CASE c
WHEN 1 THEN col1
WHEN 2 THEN col2
WHEN 3 THEN col3
END)
FROM x,
(SELECT 1 AS c
UNION ALL
SELECT 2
UNION ALL
SELECT 3) t
GROUP BY id
You have to hard code a big number say 99999.
LEAST( IFNULL(COL_1,999999) ,
IFNULL(COL_2,999999) ,
IFNULL(COL_3,999999) ,
IFNULL(COL_1,999999) )
i.e. just add IFNULL then the value or column name with a big enough integer.
Why is this query returning 0 rows?
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1<>t.f2;
This is a distilled version of a complex query I have. I want to compare two tables containing one-to-one related data and I want to select those rows that contain different values for certain fields. But also there can be the case where one row is missing in one of the tables. The LEFT JOIN correctly returns null values for these rows, but then, the WHERE clause is incorrectly (or unexpectedly) filtering these rows out.
Why -in this case- 'null' IS NOT DIFFERENT to any not null value (like 'a') ?
What is driving me crazy is that this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t;
returns 1 row (as I expected) but this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1=t.f2;
returns 0 rows !! So null is not equal to 'a' and null is not different to 'a' !!
Please... Can anybody explain this?
Exactly. NULL represents an unknown value, not any specific value (it is not the same as NULL in C, or nil in Ruby, etc.) In SQL, if you compare something to the unknown value, the result is also unknown. And you will not get the rows where WHERE condition is unknown.
Try this:
SELECT NULL <> 2;
and you will see NULL as result.
Try this:
SELECT * FROM t WHERE NULL;
and no rows will come out, even if the table t is huge.
If you really need what you said you wanted (and I am not advocating this), you can do something like this:
SELECT T.f1, T.f2
FROM (SELECT NULL f1, 'a' f2) T
WHERE ((T.f1 IS NULL OR T.f2 IS NULL)
AND (T.f1 IS NOT NULL OR T.f2 IS NOT NULL))
OR T.f1 <> T.f2
The concept of NULL is a common source of confusion for newcomers to SQL, who often think that NULL is treated as the other values.
This is not the case. Conceptually, NULL means "a missing unknown value" and therefore it is treated very differently.
What you are seeing is pretty easy to explain. Consider the following example:
CREATE TABLE mytb (id int, value int);
INSERT INTO mytb VALUES (1, 100);
INSERT INTO mytb VALUES (2, 200);
INSERT INTO mytb VALUES (3, NULL);
INSERT INTO mytb VALUES (4, 400);
The above means that for the row with id = 3, the value is "unknown". It could be 300, or it could be 100, or anything else.
Therefore when you request the following:
SELECT * FROM mytb WHERE value <> 100;
+------+-------+
| id | value |
+------+-------+
| 2 | 200 |
| 4 | 400 |
+------+-------+
2 rows in set (0.00 sec)
The row with id = 3 is not returned, because NULL <> 100 returns "unknown". We don't know if row id = 3 has a value of 100, so the expression does not return true. I doesn't return false either. It returns "unknown" (NULL).
The condition of the WHERE clause can only be satisfied when the expression is true. When you compare something to NULL, the expression can never be true. It will be "unknown".
SQL NULL does not work the way you would like it to work: http://en.wikipedia.org/wiki/Sql_null
In short, NULL = NULL is not true. NULL <> NULL is not true. NULL <> 1 is not true. And so forth.
NULL value is nothing, it can't be equal or not equal to something.
If you want to check if your value is null - use "IS NULL" statement:
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1 IS NULL
If you want to check if your values are equal or not equal - you can use COALESCE function on nullable columns:
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where COALESCE(t.f1, '')<>COALESCE(t.f2, '');
Try to do this query:
select * from dual where NULL = NULL
It returns 0 rows. That's because to compare a value with null you have to do IS NULL or IS NOT NULL, otherwise it will return false.