IN Operator SQL - sql

I have a table called NUMS with a single column n.
And I fill values 1,2,3,4,5,null in it.
Now a query
SELECT n FROM Nums
WHERE n IN (1, 2, null)
In this case I guess it's converted to
SELECT n FROM Nums
Where n = 1 OR n = 2 OR n = null
I am also comparing n with a null value which should yield unknown and it should return an empty set.But it's returning 1,2 (null is not returning, although included in IN operator)
Now a query
SELECT n FROM Nums WHERE n NOT IN(1, 2, null)
...gets converted to:
SELECT n FROM Nums
Where n!=1 AND n!=2 AND n!=null
Here what I said above works and it does not return anything.
Can anyone explain in detail what's happening.

This is because null = null is always false the operator to use for null is IS or IS NOT
You can use the query below for the expected output
SELECT n FROM Nums WHERE n IN (1,2) OR n IS NULL
[Edit]Thanx #Buckwad

OK I have found the answer
SELECT n FROM Nums
WHERE n NOT IN (1, 2, null)
evaluates to
SELECT n FROM Nums
n!=1 AND n!=2 AND n!=null
The outcome of last comparison will always be UNKNOWN.
and the truth table of AND shows that as soon as one Unknown is invloved in it (U,T)(U,F),(U,U) the reult can only be U or F (U=Unknown, F=False) and hence it will not be included in the result set.
In case of
SELECT n FROM Nums
WHERE n IN (1, 2, null)
equates to
SELECT n FROM Nums
WHERE n = 1 OR n =2 OR n=null
Now for the row with n=1, the operation n=1 will come as true
and for the row with n=2, the operation n=2 will come as true
and for all rows n=null will be unknown
So it gives 1 and 2 in the result set.
Hope u people liked it.
CAN ANYONE PLEASE MARK MY REPLY AS ANSWER

null is not returning, although included in IN operator
Because of the n = NULL evaluation; NULL can't equal NULL. It would need to be handled as n IS NULL (or similar appropriate syntax) to return the NULL row/record.

You cannot compare directly with null. To find whether the value of a column is null, you must use something along the lines of this:
SELECT n
FROM Nums
WHERE n IS NULL

I am also comparing n with a null value which should yield unknown and it should return an empty set.
it shouldn't
if you need in additional row filled with NULL values the best way imo is:
SELECT n FROM Nums WHERE n IN(1,2)
UNION
SELECT NULL
Now a query
SELECT n FROM Nums WHERE n NOT IN(1, 2, null)
...gets converted to:
Here what I said above works and it does not return anything.
thats right, because nothing can be equal to NULL and for NULL comparison IS NULL statement is used

If an IN list contains a NULL value anywhere, the result of the entire list is UNKNOWN
With the correct default of ANSI NULLS, when you compare NULL with NULL the result is not true, but UNKNOWN

SELECT n FROM Nums
WHERE n IN (1, 2)
Or n Is null
This will retrieve what you intend to get. As said by Mitch normally a comparison to Null yields UNKNOWN. This is because NULL itself is defined as an undefined value. It's like saying I lived in Nottingham, Birmingham and somewhere. Finding somewhere on the world map can prove a bit tricky as it is undefined.

Related

How to divide columns with zeros and nulls

just a simple question but somehow I can't find an answer here.
I have two columns (A and B). Both contains numbers with zeros and null. I would like to get a division one by the other to get information about the ratio between each single row but I am getting ORA-01476.
I know the divisior is equal to zero but I would like to get in this row a number and not an error for whole query
A B
1 5
2 Null
3 0
NULL 3
0 4
4
I am using sql developer.
If you divide a number by zero you get an error, because the answer to such division is undefined. SQL, however, has a value for undefined: NULL. So make the result NULLinstead:
select a, b, case when b = 0 then null else a / b end as ratio
from mytable;
or
select a, b, a / case when b = 0 then null else b end as ratio
from mytable;
This is standard SQL and works in Oracle as well as in about every other RDBMS. Oracle also provides the function NULLIF as a shorter way to write the expression in the second query.
You can use nullif to return null instead of raising an error:
select A / nullif(B, 0) as division
from YourTable
If your numbers are stored as varchar, cast them to numbers before using them:
select to_number(A) / nullif(to_number(B), 0) as division
from YourTable

What is the difference between NOT and != operators in SQL?

What is the difference between NOT and != operators in SQL? I can't understand the difference. I guess they are same.
NOT negates the following condition so it can be used with various operators. != is the non-standard alternative for the <> operator which means "not equal".
e.g.
NOT (a LIKE 'foo%')
NOT ( (a,b) OVERLAPS (x,y) )
NOT (a BETWEEN x AND y)
NOT (a IS NULL)
Except for the overlaps operator above could also be written as:
a NOT LIKE 'foo%'
a NOT BETWEEN x AND y
a IS NOT NULL
In some situations it might be easier to understand to negate a complete expression rather then rewriting it to mean the opposite.
NOT can however be used with <> - but that wouldn't make much sense though: NOT (a <> b) is the same as a = b. Similarly you could use NOT to negate the equality operator NOT (a = b) is the same as a <> b
This question actually makes a lot more sense than people give it credit for.
Firstly, original SQL not-equal operator was <>, and only later on the C-style != was added as far as I know. I personally always use <> as != looks strange to me, but I'm old school.
Secondly, of course the original asker didn't mean to compare NOT with !=, but rather the difference between NOT a = b vs. a != b. And intuitively there should be a difference, but for all I know there isn't.
To make this all clear, here is an example session run on PostgreSQL (in Oracle you need more weird stuff such as SELECT ... FROM DUAL UNION ..., etc., which I avoid for the sake of brevity):
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst;
a | b
---+---
1 | 2
2 | 3
4 |
(3 rows)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b = 2;
a | b
---+---
1 | 2
(1 row)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b != 2;
a | b
---+---
2 | 3
(1 row)
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where not b = 2;
a | b
---+---
2 | 3
(1 row)
Here we may think that this last query should also have returned the row (4, NULL). But it didn't. In PostgreSQL I can actually inspect this further, as follows:
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select *, b = 2 as beq2 from tst;
a | b | beq2
---+---+------
1 | 2 | t
2 | 3 | f
4 | |
(3 rows)
You see that the Boolean expression b = 2 is NULL for the case where b is NULL. However, when a Boolean expression is NULL it is treated as false, or rather not true. And when you negate it with NOT, the Boolean value of the expression stays NULL and therefore is still not true.
Unfortunately I know of no other way than to handle NULL cases explicitly, so I have to write:
db=# with tst(a, b) as ( values (1,2), (2,3), (4, null) ) select * from tst where b is null or b = 2;
a | b
---+---
1 | 2
4 |
(2 rows)
So, instead of writing NOT <Boolean expression> you always have to write a IS NULL OR b IS NULL OR ... OR z IS NULL OR f(a, b, ..., z) where a, b, ..., z are variables in the given Boolean expression f(...).
It would be so much easier if instead of just NOT there were the Boolean operators MAYBE and CANNOT. So you could write WHERE MAYBE b = 2 or WHERE CANNOT b = 2 instead of this complicated OR combination of a bunch of IS NULL tests before your actual condition.
!= is a binary operator that returns true if its two arguments are not equal to each other.
NOT is a unary operator, which reverses its argument, a Boolean expression.
For example, this expression: a < 10 is true when a is any value less than 10. This condition can be negated: NOT a < 10. Negating this condition makes it true in the opposite cases, i.e. when a not less than 10. It's the same as a >= 10.
The expression a != 10 is true when a is any value less than 10 or any value greater than 10. This is a completely different case from a condition negated with NOT.
Both NOT operator and != almost serve a similar purpose.Both are used in Where clause of an sql query.
NOT operator shows records when a particular condition is not true.
Example:
SELECT * FROM Employees
WHERE NOT Country='Germany'
will get you records with all employees with countries other than Germany.
The != operator similarly checks if the values of two operands are equal or not, if values are not equal then condition becomes true.
Example:
SELECT * FROM Employees
WHERE Country!='Germany'
will get you all rows with country column having country other than Germany.

Why does AVG(x) give a different answer than AVR((isnull(x,0))?

X is column with a mixture of numerical and null values.
I don't understand why treating null values as 0 changes the result of the AVG value.
Shouldn't it be like this,
(2 + null + 2) / 3 = 2 -- with null value
(2 + 0 + 2) / 3 = 2 -- no null value
If you have null value, it is not being taken into account, hence number of elements (your n) is not increased, whereas 0 is treated as a valid value.
For example if you have: 1,1,6,7,null,3,2 it will be total 20 divided by 6 (i.e. 3.33). However if you replace null with 0 it becomes 20 /7 (i.e. 2.86).
SQLFiddle demonstrating this behavior on MySQL server.
REFERENCE: Have a look in the documentation right below the table:
This section describes group (aggregate) functions that operate on sets of values. Unless otherwise stated, group functions ignore NULL values.

SQL query to add values of two columns containing null values?

Given table:
ID ONE TWO
X1 15 15
X2 10 -
X3 - 20
This query:
SELECT (ONE + TWO) FROM (TABLE)
Just returns the sum of X1's values but not the others since at least one column has a null value. How can I still add them even if there is a null? i.e. consider the null as a 0 maybe?
SELECT (COALESCE(ONE, 0) + COALESCE(TWO, 0)) FROM (TABLE)
COALESCE will return the first non-null value found in the parameters from left to right. So, when the first field is null, it will take the 0.
That way, X2 will result in 10 + 0 = 10
there is already a good answer, but I think it is worth mention to the antonpug (in case he doesn't know) that the reason why this is happening is that NULL is not a value that can be compared or summed.
NULL isn't 0 or '' (empty string), so every operation involving NULL will result NULL (10 + NULL = NULL), even (NULL=NULL) will evaluate to FALSE

Finding even or odd ID values

I was working on a query today which required me to use the following to find all odd number ID values
(ID % 2) <> 0
Can anyone tell me what this is doing? It worked, which is great, but I'd like to know why.
ID % 2 is checking what the remainder is if you divide ID by 2. If you divide an even number by 2 it will always have a remainder of 0. Any other number (odd) will result in a non-zero value. Which is what is checking for.
For finding the even number we should use
select num from table where ( num % 2 ) = 0
As Below Doc specify
dividend % divisor
Returns the remainder of one number divided by another.
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/modulo-transact-sql#syntax
For Example
13 % 2 return 1
Next part is <> which denotes Not equals.
Therefor what your statement mean is
Remainder of ID when it divided by 2 not equals to 0
Be careful because this is not going to work in Oracle database. Same Expression will be like below.
MOD(ID, 2) <> 0
ID % 2 reduces all integer (monetary and numeric are allowed, too) numbers to 0 and 1 effectively.
Read about the modulo operator in the manual.
In oracle,
select num from table where MOD (num, 2) = 0;
dividend % divisor
Dividend is the numeric expression to divide. Dividend must be any expression of integer data type in sql server.
Divisor is the numeric expression to divide the dividend. Divisor must be expression of integer data type except in sql server.
SELECT 15 % 2
Output
1
Dividend = 15
Divisor = 2
Let's say you wanted to query
Query a list of CITY names from STATION with even ID numbers only.
Schema structure for STATION:
ID Number
CITY varchar
STATE varchar
select CITY from STATION as st where st.id % 2 = 0
Will fetch the even set of records
In order to fetch the odd records with Id as odd number.
select CITY from STATION as st where st.id % 2 <> 0
% function reduces the value to either 0 or 1
It's taking the ID , dividing it by 2 and checking if the remainder is not zero; meaning, it's an odd ID.
<> means not equal. however, in some versions of SQL, you can write !=