Is there any diference between "!= NULL" and "IS NOT NULL" in MySQL? - mysql

Is there any difference between using "!= NULL" and using "IS NOT NULL"?
For example:
SELECT * FROM tbl_example WHERE a_field IS NOT NULL
and
SELECT * FROM tbl_example WHERE a_field != NULL

Yes, there is. != does not work properly with NULL1:
mysql> SELECT 1 != NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 != NULL | 1 IS NOT NULL |
+-----------+---------------+
| NULL | 1 |
+-----------+---------------+
1 row in set (0.00 sec)
BTW: != is not valid SQL, you should use the diamond operator <>.
1 In fact no comparison, except IS and IS NOT works.

You shouldn't compare values to null, becouse efect of this operation isn't true neither false - it's always unknown.
To check is value null, you should always use is null

Related

SELECT count(*) with where produces weird values

It seems when I am trying to make a query to get the users transaction sum, it does not return the proper value until I remove the filter on code, what is even more interesting is the filter on the bar code following works perfectly fine, it seems maybe there is an inconsistency between both the subqueries in the WHERE clause?
Explanation:
With the below query, when I remove the and code != "foo" AND code !="foobar" from the query, it returns the correct value, but I also tried changing it to code = "foo" or code = "foobar" to check if any of the results had these codes, and it returns null when I do this.
SELECT SUM(t.amount)
FROM transactions t
WHERE `t`.`deleted_at` IS NULL
AND `t`.`user_id` = 80
AND `t`.`user_id` IS NOT NULL
AND `manually_deleted_at` IS NULL
AND
(SELECT count(*)
FROM `transaction_subcategories` s
WHERE `t`.`transaction_subcategory_id` = `s`.`id`
AND `code` != "foo"
AND `code` != "foobar"
AND
(SELECT count(*)
FROM `transaction_categories` c
INNER JOIN `transaction_categories_transaction_subcategories` sc ON `c`.`id` = `sc`.`transaction_category_id`
WHERE `sc`.`transaction_subcategory_id` = `s`.`id`
AND `code` = "bar") >= 1) >= 1
AND `posted_date` BETWEEN "2016-04-01 00:00:00.000000" AND "2017-03-31 23:59:59.000000"
AND `parent_id` = 0;
While I do realize this is a mysql query issue, the laravel ORM code is a bit cleaner:
$income_transactions = \Auth::user ()->transactions ()
->notManuallyDeleted()
->whereHas('transactionSubcategory', function ($query) {
$query
->where('code', '!=', 'foo')
->where('code', '!=', 'foobar')
->whereHas('transactionCategories', function ($query2){
$query2->where('code', '=', 'bar');
});
})
->whereBetween ( 'posted_date', [$from,$to])
->where('parent_id', '=', 0)
->get ();
Update
Not sure if this helps, but I did a query to see which subcategories it is returning with the WHERE clause and it returns only ones where the code is NULL
mysql> SELECT * FROM transaction_subcategories WHERE id in ('1125', '630', '1395') AND code is null;
+------+-----------------------------------+------+---------+
| id | name | code | user_id |
+------+-----------------------------------+------+---------+
| 630 | foo | NULL | 80 |
| 1125 | foo | NULL | 80 |
| 1395 | foo | NULL | 80 |
+------+-----------------------------------+------+---------+
Update 2 Turns out it is the WHERE doing it, it seems that NULL values won't be compared against a string, in other words if I do a WHERE on a column that has nulls, the null value rows will disappear
Answer Turns out adding OR code is null in a group in the WHERE clause was all I needed. Closed :)

MYSQL return row

I've a table with records in mysql as below and I would like to get the result, if no value in receivedfmuser and topm then no record (means 0 row) will be displayed, but mysql doesn't work as mysql still count it as 1 row?
select receivedfmuser, topm from tb_postatus where pono = 36 and receivedfmuser is not null and topm is not null
TABLE
|tid|pono|receivedfmuser|topm |
|1 |36 |02/02/2015 | |
|2 |27 |02/03/2015 |02/03/2015|
In your above example, the value in topm in row1 is actually an empty string value and not NULL. That is why it satisfies not null condition and is displaying the record. So, use the following
select receivedfmuser, topm from tb_postatus
where pono = 36 and
receivedfmuser != '' and
topm != ''
This wont display the rows having NULL and also those having an empty string value.
Try below query
select receivedfmuser, topm
from tb_postatus
where pono = 36
and receivedfmuser is not null
and receivedfmuser != ""
and topm is not null
and topm != ""
If in above example the value you are checking for null is topm, then the issue is your query because your query is validating "receivedfmuser" as not null value.
select t.receivedfmuser, t.topm, t.pono
from test t
where `receivedfmuser` IS NOT NULL;
receivedfmuser, topm, pono
'02/02/2015', NULL, '36'
'02/02/2015', '02/03/2015', '27'
Then changing the query to "topm"
select t.receivedfmuser, t.topm, t.pono
from test t
where `topm` IS NOT NULL;
receivedfmuser, topm, pono
'02/02/2015', '02/03/2015', '27'
The result show 1 row the one with topm not null.
With your example :
select t.receivedfmuser, t.topm, t.pono
from test t
where `topm` IS NOT NULL and t.pono = 36;
receivedfmuser, topm, pono
Not result is returned.
Hope this helps.
And yes, if the value you are checking to be null is actually an empty value, your query will not work as mysql will not understand null as an empty string.

How to achieve default value if column value is NULL?

I want to retrieve some column values from table with these conditions.
If value is NULL (or) Empty String , return some user defined value
If not above condition , return it's value.
How can I figure it out ?
Here is my Table query..
CREATE TABLE AUCTION_CAR_BID(
bid_seq bigint NOT NULL AUTO_INCREMENT,
auction_car_seq bigint NOT NULL,
bid_group_seq bigint NOT NULL,
bid_price int DEFAULT 0 NOT NULL,
over_bid_price int DEFAULT -1 NOT NULL,
result_id int DEFAULT 0 NOT NULL,
remark varchar(500),
PRIMARY KEY (bid_seq))
ENGINE = InnoDB DEFAULT CHARACTER SET utf8;
Here is my efforted codes to get it..
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
Another :
SELECT
CASE
WHEN OVER_BID_PRICE IS NULL
OR TRIM(OVER_BID_PRICE) = '' THEN -1
ELSE OVER_BID_PRICE
END OVER_BID_PRICE
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
But I always get empty String value(not -1) if given id is not in my table.
Any suggestions would be really appreciated !
If you write this:
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
The results can be two types.
First result: Your query no returns rows! Your WHERE condition is unsatisfact so you'll read NULL
Second result: Your query returns rows but the value of your field is NULL, your COALESCE works fine in this case
To resolve you can try this:
SELECT COALESCE(
(SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM AUCTION_CAR_BID
WHERE BID_SEQ = 2354435345)
,-1);
Tell me if it's OK
How about this:
select
case when price is null or id <> 1
then -1
else price
end price
from mytable
DROP TABLE prices;
CREATE TABLE prices (price_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,price INT NULL);
INSERT INTO prices (price) VALUES (' '),(''),(NULL);
SELECT * FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | NULL |
+----------+-------+
SELECT price_id,COALESCE(price,-1) price FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | -1 |
+----------+-------+
If there's no row for USER_SEQ = 2354435345 in your table there's no row returned. But aggregate functions always return a row even if the result is empty :-)
SELECT
COALESCE(MIN(OVER_BID_PRICE), -1)
FROM
USER_PARAM
WHERE
USER_SEQ = 2354435345;

MYSQL: enum field searching with NULL values

table person:
name
type enum('admin','user','random') NULL DEFAULT NULL
When this query is performed, it doesnt return the records that have a type of NULL
select * from person where type != 'admin';
null cannot be tested for with (in)equality statements. you need to use IS NULL. e.g.
select *
from person
where (type != 'admin') or (type IS NULL)
e.g. null is "contagious"
null > x -> null
null = x -> null
null = null -> null
null + 1 -> null
null * 1 -> null
etc... it's basically "unknown". Mixing known and unknown in sql makes the result unknown, always. Hence the special ifnull(), coalesce(), and "if null" tests/functions.
You can use the NULL safe equality operator in MySQL
select *
from person
where not type <=> 'admin'

MYSQL Using UPDATE, WHEN THEN with a NULL value

I'm trying to figure out why I'm not getting a result from a MySQL Query I'm running.
I'm trying to replace a NULL value with a number with in a query, but I can't figure out what I'm doing wrong.
Here's my query:
UPDATE Details
SET HowHear_ID = CASE HowHear_ID
WHEN '' THEN 25
WHEN NULL THEN 25
WHEN 7 THEN 25
WHEN 8 THEN 5
WHEN 16 THEN 25
WHEN 17 THEN 16
END
WHERE HowHear_ID IN ('',NULL,7,8,16,17)
This Query will effect all but the NULL values.
What am I doing wrong??
No value will ever equal (or "unequal") NULL in SQL. Understand the following truth table:
NULL = NULL yields NULL -- not FALSE!
NULL != NULL yields NULL -- not TRUE!
[ANY] = NULL yields NULL -- not FALSE!
[ANY] != NULL yields NULL -- not TRUE!
Since the following are equivalent...
[expression] IN (a, b, c)
[expression] = ANY (a, b, c)
[expression] = a OR [expression] = b OR [expression] = c
... you cannot put NULL on the right hand side of an IN predicate. Interestingly, things get even worse when you put NULL on the right hand side of a NOT IN predicate:
[expression] NOT IN (a, b, c)
[expression] != ANY (a, b, c)
[expression] != a AND [expression] != b AND [expression] != c
If b were NULL, the whole expression will become NULL (or maybe FALSE), but never TRUE. This is also the case for NOT IN (subselect) predicates! So, never do this:
[expression] NOT IN (NULL, 1, 2)
The correct solution in your case uses a NULL predicate instead. Do this:
UPDATE Details
SET HowHear_ID = CASE
WHEN HowHear_ID = '' THEN 25
WHEN HowHear_ID IS NULL THEN 25 -- Use a NULL predicate here
WHEN HowHear_ID = 7 THEN 25
WHEN HowHear_ID = 8 THEN 5
WHEN HowHear_ID = 16 THEN 25
WHEN HowHear_ID = 17 THEN 16
END
WHERE HowHear_ID IN ('',7,8,16,17)
OR HowHear_ID IS NULL -- Use a NULL predicate here
Or this:
WHERE COALESCE(HowHear_ID, '') IN ('',7,8,16,17)
You can't reference NULL in a WHERE clause and get the results you expect. NULL behaves differently to other values.
If you need to reference it, you need to use the isnull() function.
in your case, you would write something like this:
WHERE HowHear_ID IN ('',7,8,16,17) or isnull(HowHear_ID)
By the way, you haven't specified the data type of the field. I assume it's an integer though. In that case, it might be better to check for zero rather than an empty string? (if it isn't an integer, then perhaps it should be)
You can achieve that with
WHERE HowHear_ID IN ('',7,8,16,17) OR HowHear_ID IS NULL