Why don't counts using 'LIKE' in SQL match? - mysql

I have one table ABC with EMPLID, GRADE, SALARY and DATE as its fields.
I am executing the following 3 statements:
select count(*) from ABC;
Result :- 458
select count(*) from ABC where GRADE LIKE '%def%';
Result :- 0
select count(*) from ABC where GRADE NOT LIKE '%def%';
Result :- 428
My point here is: the result of second query plus the result of third query should be equal to the result of first query, shouldn't it?

Looks like you have 30 records where the GRADE is null.
null values are unknown, so do not match either condition.

Sql uses a three-valued logic: true, false &unknown. If you compare a NULL to any other value the result is unknown. NOT(unknown) is still unknown.
A WHERE clause only returns rows that evaluate to true. So the missing 30 rows in your example have a NULL in the Grade column.

Note that apart from the obvious case where you can have NULL values in your table (as others have mentioned), you could also have empty strings.
In Oracle:
-- Returns nothing
select 1 from dual where '' like '%'
In MySQL:
-- Returns 1
select 1 from dual where '' like '%'
Since you tagged your question with both oracle and mysql, you might be running into an incompatibility here, as in oracle '' IS NULL holds true!

Related

Why does <> 'null' works in MySQL?

Hope the question is not too generic. Couldn't find anything on the site or in SQL documentation:
While coding, i tested this, and to my surprise it worked:
SELECT * FROM cal_entry WHERE cal_entry.parent_id <> 'null'
It actually shows the rows without the ones with NULL values (these are real NULL values in database, not strings with 'null' inside).
According to the docs, I should have used NOT NULL, of course. By the way, it doesn't work with = 'null', like it is correctly stated in the docs.
Can someone explain that?
You are selecting all rows where <> 'null' is true.
Comparing(equals or not-equals) to null is null, so if a row where cal_entry.parent_id is null, your condition will be false/null.
So your query gets all rows that are not null, nor contain the string 'null'.
(Note, you could just as well have written <>'something_else')
Assuming parent_id in an int column the query will return all non-null, non-zero rows:
SELECT *
FROM (
SELECT NULL AS parent_id UNION ALL
SELECT 0 UNION ALL
SELECT 1 UNION ALL
SELECT 2
) AS cal_entry
WHERE cal_entry.parent_id <> 'null'
-- returns 1 and 2 but not 0!
When comparing a number to string MySQL will convert the string to number. Some examples:
'null' becomes 0
'asdf' becomes 0
'1asdf' becomes 123
'1' becomes 1
Your query will behave like:
WHERE cal_entry.parent_id <> 0
this operator give you result of not equal to. ex. $var != null.
we write in mysql as <>. this is kind of validation that the value shoud never be equal to null.
When working with null following two statements should always be taken note of -
An expression can be null, but it can never be equal to null.
Two nulls are never equal to each other.
So, in your query wherever there is a comparison null<>null it returns true by second statement.
Also, always account the possibility that some rows might contain null -
Select * from cal_entry where cal_entry.parent_id!=10
This query would leave out the rows with null entries. Instead use -
Select * from cal_entry where cal_entry.parent_id!=10 or cal_entry.parent_id is null

sum two or more columns in mysql table but leave out the null field

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.

MySql IFNULL function in query

i am using mysql ifnull in query, if the id is null then it should return 1 but it is not working, i think the syntax is good... what is the problem?
the query i am using is:
SELECT IFNULL(id,1) autoid FROM tb_orders
You may try with COALESCE like this:
SELECT COALESCE(id,1) autoid FROM tb_orders
Just to add after watching your comments, the above query is usefull only when your table has records on it. Querying on emplty table is like trying to get icecream from the empty refrigerator! ;-)
For handling empty table you need to check if number of rows returned is zero or not
SELECT case COUNT(*) when 0 then 1 else IFNULL(id,1) END as autoid
FROM tb_orders
SQL Fiddle Demo for Empty table
But in my opinion you should use other value than 1 for autoid when table is empty to differentiate between non empty table with NULL value and empty table.
SELECT case COUNT(*) when 0 then -1 else IFNULL(id,1) END as autoid
FROM tb_orders

What count(predicate) is doing in MySQL?

I was surprised to see one of my students writing
select count(title='Staff') from titles
against MySQL employees database. Does it mean to be a nice shortcut for
select sum(case when title='Staff' then 1 else 0 end) from titles
which just fails to work in MySQL 5.6 (returning full table count)?
No, this count is not a shorthand for the sum you wrote.
COUNT(exp) counts the number of rows with a not null exp.
title='Staff' is a Boolean expression, which evaluates to true if title is 'Staff', false if it's any other value or null if it's null.
So, this query is equivalent to
select count(title) from titles
which, in turn, is equivalent to
select count(*) from titles where title is not null
No!
You can't count against an condition write into brackets. It simple return all rows from that table.
select count(title='Staff') from titles
return all rows from titles

Pass number as a column name in select statement of Sql

My query is like this
select 5 from mytable_name;
Then the output is like column name 5 and the value is 5 printing as many max number of rows exists in that table.
Can anybody tell the reason why this query is working like this?
Can anybody tell the reason why this query is working like this?
You are selecting a string literal value '5' for each row in your table:
select 5 from mytable_name;
And this works fine. Because in the SELECT statement you can select:
Column reference,
Literal value like in your case.
Function.
value expression.
Select expression.
As defined by the standard SQL1:
Update:
However, If you have a column with a name is a number like in your case, you have to escape it in order to select the values in it like so:
SELECT `143` FROM Table1;
This will select all the rows in the column 143.
But, this:
SELECT 143 FROM Table1;
Will select the string literal 143 for each row found in the table.
Note that: If possible, try not to name these columns this way, it is recommended and a best practice, not to do this.
SQL Fiddle Demo
Update 2:
Note that, if you select 143 or '143', or even "143" this will select the literal value 143 not the column date. The following are the same:
SELECT 143 FROM Table1;
SELECT '143' FROM Table1;
SELECT "143" FROM Table1;
All these SELECTs won't select the data in the column, They will select the literal value 143 not the column data. See this demo:
Demo
You have to escape the column name with the two:
``
Like this:
SELECT `143` FROM table1;
Not:
SELECT '143' FROM table1'
Like what I did here:
The right Demo
1Image From: SQL Queries for Mere Mortals
from mytable
will select all rows from your table if there is no where condition that shrinks that result. and
select 5
will select the constant number 5 for every record. If you use a column name in the select part then that value will be selected for every record.
The DB engine will name the result 5 because it automatically generates a column name and 5 is the logical name for that.
You want 'SELECT * FROM mytable_name LIMIT 0,5' perhaps?
Since you don't have anything in your where clause, it is selecting all the rows from your table. The fact that you don't select any of the columns is irrelevant - you'll still get a result for each row in the table.
With the command select 5 ... you are viewing a fixed value. Same thing you run the following command: select "test", you will be displaying a fixed string.
Using ... from mytable_name you're looking for all record of this table.
With this we can conclude that for each record in the table mytable_name shows you the fixed value "5".