MySQL strange behaviour for comaprison operator (!=/<>) i.e. NotEqualTo - mysql

I am using simple WHERE clause to fetch records from a table using NotEqualTo comparison. Ironically it doesn't return recrods where column has no value at all.
Query
SELECT * FROM TABLE WHERE COL<>'Something'
Above query will return all records where COL isNotEqual to Something, however, It doesn't return those where COL is empty or NULL.
Why is that so?
It should return records where COL is empty/null as it still satisfies the condition that it isn't equal to 'Something'

Okies thanks guys for helping me out. I didn't know about this behaviour. For others to handle this issue, I modified query as below to get required results:
SELECT * FROM TABLE WHERE COL IS NULL OR COL<>'Something'

Check Manual for arithmetic comparison.
You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL.
Check SQL Fiddle

Related

How Coalesce function deals with datatype

I am new to COALESCE function in REDSHIFT. I ran below four queries in mysql and Redshift.
1st and 2nd query executed as expected in both mysql and redshift. But for 3rd and 4th query I am getting two different results in mysql and Redshift. How does this behave?
select COALESCE(null,null,1) -> 1
select COALESCE(null,null,'John') -> 1
select COALESCE(null,null,1,'John') -> (Redshift : error , mysql:1)
select COALESCE(null,null,'John',1) -> (Redshift: error, mysql:John)
Also this query should give error in mysql but it has succeeded
Any help is appreciated
Amazon Redshift Database Developer Guide claims:
An NVL expression is identical to a COALESCE expression. NVL and
COALESCE are synonyms.
Syntax
NVL | COALESCE ( expression, expression, ... )
An NVL or COALESCE expression returns the value of the first expression
in the list that is not null. If all expressions are null, the result
is null. When a non-null value is found, the remaining expressions in
the list are not evaluated.
This type of expression is useful when you want to return a backup
value for something when the preferred value is missing or null. For
example, a query might return one of three phone numbers (cell, home,
or work, in that order), whichever is found first in the table (not
null).
If you obtain the error this may mean that the returned value datatype do not match the datatype of recordset field or any another structure which must accept the returned value.
PS. Will you show error messages?
Though it is not written in the documentation, but coalesce works on the compatible data types. Integer and varchar cannot be compared.
The error becomes more evident when you provide column name instead of hard-code values. Try executing this:
select coalesce(integer_column, varchar_column) from a_table;
You would get an error saying something like this:
coalesce types integer and varchar cannot be matched.

mysql where clause field

I am trying to understand a piece of mysql code:
Select * from tableA
where type = 'blue'
and status = 'confirmed'
and statement
and date between '2017-01-01' and '2017-12-31'
Would would the "and statement" mean where statement is a field but without an =, or, and, >, < ect.
Thanks in advance
This is a MySQL peculiarity that other database engines do not exhibit. In other DBMS the equivalent would be:
and statement<>0
An empty where condition, as above, is effectively the same as AND LENGTH(statement) > 0. So any non-empty value in the statement column will be returned.

In MySQL select query, checking for a string or checking for true in a where clause?

Consider the following table:
SELECT id, Bill_Freq, Paid_From, Paid_To, Paid_Dt, rev_code FROM psr_20160708091408;
The requirement is to fetch the row which has rev_code populated with the string **SUM**.
I've also noticed that for every row with rev_code populated as **SUM** its Bill_Freq won't be either null or zero.
So I wrote two queries to fetch the row with the lowest id
Query based on string check in where clause:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**";
Query based on true condition:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where bill_freq;
I haven't seen anyone use the second type, would like to know its reliability and circumstance of failure.
If by "second type" you mean a where clause with no explicit condition, then there is a good reason why you do not see it.
The SQL standard -- and most databases -- require explicit conditions in the where. MySQL allows the shorthand that you use but it really means:
where not billing_freq <=> 0
or equivalently:
where billing_freq <> 0 or billing_freq is null
(The <=> is the null-safe comparison operator.
The more important issue with your query is the min(). I presume that you actually want this:
select p.*
from psr_20160708091408 p
where rev_code = '**SUM**'
order by id
limit 1;
Also, you should use single quotes as string delimiters. That is the ANSI standard and there is rarely any reason to use double quotes.
Actually you can use the second type of query, but as your requirement is based on rev_code, it is always good to have condition with rev_code, because of 2 reasons
Bill_Freq having no NUlls or Zeros might be assumption based on current data
Even if it is true, in future, your application logic might change and it might have a scenario having NULL or zero, which will break your logic in future.
So my suggestion is to use first query with Rev_code
Please try to use below query
select
id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**" ORDER BY ASC LIMIT 0,1;
Thanks.
The requirement says it itself.
The requirement is to fetch the row which has rev_code populated with
the string '**SUM**'
In the scenario that bill_freq IS NOT NULL and rev_code is populated with
the string '**SUM**' then your logic will obviously fail.
Go for
where rev_code = "**SUM**";

MySQL returns all rows when field=0 from SECOND Select query

This case is similar to: S.O Question; mySQL returns all rows when field=0, and the Accepted answer was a very simple trick, to souround the ZERO with single quotes
FROM:
SELECT * FROM table WHERE email=0
TO:
SELECT * FROM table WHERE email='0'
However, my case is slightly different in that my Query is something like:
SELECT * FROM table WHERE email=(
SELECT my_column_value FROM myTable WHERE my_column_value=0 AND user_id =15 LIMIT 1 )
Which in a sense, becomes like simply saying: SELECT * FROM table WHERE email=0, but now with a Second Query.
PLEASE NOTE: It is a MUST that I use the SECOND QUERY.
When I tried: SELECT * FROM table WHERE email='( SELECT my_column_value FROM myTable WHERE my_column_value=0 LIMIT 1 )' (Notice the Single Quotes on the second query)
MySql SCREAMED Errors near '(.
How can this be achieved
Any Suggestion is highly honored
EDIT1: For a visual perspective of the Query
See the STEN_TB here: http://snag.gy/Rq8dq.jpg
Now, the main aim is to get the sten_h where rawscore_h = 0;
The CURRENT QUERY as a whole.
SELECT sten_h
FROM sten_tb
WHERE rawscore_h = (
SELECT `for_print_stens_rowscore`
FROM `for_print_stens_tb`
WHERE `for_print_stens_student_id` =3
AND `for_print_stens_factor_name` = 'Factor H' )
The result of the Second Query can be any number including ZERO.
Any number from >=1 Works and returns a single corresponding value from sten_h. Only =0 does not Work, it returns all rows
That's the issue.
CORRECT ANSWER OR SOLUTION FOR THIS
Just in case someone ends up in this paradox, the Accepted answer has it all.
SEE STEN_TB: http://snag.gy/Rq8dq.jpg
SEE The desired Query result here: http://snag.gy/wa4yA.jpg
I believe your issue is with implicit datatype conversions. You can make those datatype conversions explicit, to gain control.
(The "trick" with wrapping a literal 0 in single quotes, that makes the literal a string literal, rather than a numeric.)
In the more general case, you can use a CAST or CONVERT function to explicitly specify a datatype conversion. You can use an expression in place of a column name, wherever you need to...
For example, to get the value returned by my_column_value to match the datatype of the email column, assuming email is character type, something like:
... email = (SELECT CONVERT(my_column_value,CHAR(255)) FROM myTable WHERE ...
or, to get the a literal integer value to be a string value:
... FROM myTable WHERE my_column_value = CONVERT(0,CHAR(30)) ...
If email and my_column_value are just indicating true or false then they should almost certainly be both BIT NOT NULL or other two-value type that your schema uses for booleans. (Your ORM may use a particular one.) Casting is frequently a hack made necessary by a poor design.
If it should be a particular user then you shouldn't use LIMIT because tables are unordered and that doesn't return a particular user. Explain in your question what your query is supposed to return including exactly what you mean by "15th".
(Having all those similar columns is bad design: rawscore_a, sten_a, rawscore_b, sten_b,... . Use a table with two columns: rawscore, sten.)

mysql substring get only characters

I have records like these:
RCV0001
RCV0002
RTN0003
RTN0004
SLE0005
RCV0006
I want to query for records that start with 'RCV' only and display only records.
This is what I've tried so far:
select substring(documentnumber, 1)
LIKE '%RCV%'
from transactionheader
But I'm not getting my desired result. Any ideas? I'd gladly appreciate your help. Thanks.
Will need to add a filter on the where statement
select documentnumber
from transactionheader
where documentnumber LIKE 'RCV%'
The expression in the select list of your query returns a boolean, so the query will only return 0, 1 or NULL for every row in the table.
SELECT SUBSTRING(documentnumber, 1) LIKE '%RCV%'
FROM transactionheader
For every row in the table, the first character of documentnumber will be inspected to see if it contains the string 'RCV', which will never be true. The query is going to return 0 or NULL for every row.
There is more than one query that will return documentnumber that start with 'RCV'. Here is one example:
SELECT h.documentnumber
FROM transactionheader h
WHERE h.documentnumber LIKE 'RCV%'
The WHERE clause specifies the conditional tests that will be performed on each row, only rows that "satisfy" the predicate will be returned.
Your original query has no WHERE clause so everything is being selected. Also, I would recommend using REGEXP instead. Here is my rewritten example.
SELECT substring(documentnumber, 1)
FROM transaction header
WHERE documentnumber REGEXP '^RCV'
;