Unable to retrieve NULL data - sql

I have three fields Category, Date, and ID. I need to retrieve data that does not belong under certain ID. Here is an example of my query:
SELECT Category, Date, ID
FROM table
WHERE ID NOT IN('1','2','3')
AND Date = '01/06/2015'
After running this query I should only get records that do not have any ID meaning NULL values because for yesterday's record only ID 1,2,3 exist and rest do not have any value (NULL). For some reason when I run the query it takes away the NULL values as well so I end up with 0 rows. This is very stranger to me and I do not understand what is the cause. All I know that the ID numbers are string values. Any suggestions?

Try this. NULL values cannot not be equated to anything else.
SELECT Category, Date, ID
FROM table
WHERE (ID NOT IN('1','2','3') OR ID IS NULL)
AND Date = '01/06/2015'

Others have already shown how to fix this, so let me try to explain why this happens.
WHERE ID NOT IN('1','2','3')
is equivalent to
WHERE ID <> '1' AND ID <> '2' AND ID <> '3'
Since NULL <> anything yields UNKNOWN, your expression yields UNKNOWN and the record in question is not returned.
See the following Wikipedia article for details on this ternary logic:
Null (SQL): Comparisons with NULL and the three-valued logic (3VL)

Take a look at NULL comparison search conditions.
Use the IS NULL or IS NOT NULL clauses to test for a NULL value. This
can add complexity to the WHERE clause. For example, the TerritoryID
column in the AdventureWorks2008R2 Customer table allows null values.
If a SELECT statement is to test for null values in addition to
others, it must include an IS NULL clause:
SELECT CustomerID, AccountNumber, TerritoryID
FROM AdventureWorks2008R2.Sales.Customer
WHERE TerritoryID IN (1, 2, 3)
OR TerritoryID IS NULL
If you really want to be able to compare values to NULL's directly, you can do that as well. This is also described in the above article:
Transact-SQL supports an extension that allows for the comparison
operators to return TRUE or FALSE when comparing against null values.
This option is activated by setting ANSI_NULLS OFF.

Are you sure about you want ID fields as null?
Here is how you do it: (Assumins rest of your query is ok)
SELECT Category, Date, ID
FROM table
WHERE ID IS NULL
AND Date = '01/06/2015'
If you want records that does not have a category than you need to change your query as
SELECT Category, Date, ID
FROM table
WHERE Category IS NULL
AND Date = '01/06/2015'

You got a couple of options:
SELECT Category, Date, ID
FROM table
WHERE ISNULL(ID, '4') NOT IN('1','2','3')
AND Date = '01/06/2015'
Or what su8898 said

Please note that when you use "IN" or "NOT IN" which will not fetch any values if the column has got NULL values..
In your case, if you want to fetch only records with ID=NULL, then you can try the solution vgSefa suggested above..
If you want to pull all records with NULL as well as ID NOT IN('1','2','3'), then you could try something like this..
SELECT Category, Date, ID
FROM table
WHERE ID IS NULL
AND Date = '01/06/2015'
UNION ALL
SELECT Category, Date, ID
FROM table
WHERE ID NOT IN('1','2','3')
AND ID IS NOT NULL
AND Date = '01/06/2015'

Try this:
SELECT Category, Date, ID
FROM table
WHERE ID N
AND Date = '01/06/2015'

Related

Is it possible to use WHERE with ANY and ARRAY together?

I have a table called 'reviews' that I want to start the data cleaning process, so I want to find out if there are any records that have any NULL columns (there are 6 columns in the table).
So, instead of using the code below:
SELECT *
FROM reviews
WHERE listing_id IS NULL
OR id IS NULL
OR date IS NULL
OR reviewer_id IS NULL
OR reviewer_name IS NULL
OR comments IS NULL
'''
I would like to simplify the code, using something like this:
SELECT *
FROM reviews
WHERE ANY( ARRAY [listing_id, id, date, reviewer_id, reviewer_name, comments]) IS NULL
But It doesn't work.
What's wrong with the second code?
Are there other more efficient ways to check?
you can use num_nulls()
where num_nulls(listing_id, id, date, reviewer_id, reviewer_name, comments) > 0

Use WHERE clause only if item is set, otherwise select all rows

In my Apex Oracle application I have a report using this sql query:
select ID,
NAME,
ADDRESS,
TYPE,
COMPANY_ID as "Company"
from WORKSTATIONS where COMPANY_ID = :P11_FILTER
which filters data by value of :P11_FILTER item. Now I need to select all rows if :P11_FILTER is not set or is NULL. How could I modify the where clause in order to achieve that?
You could use coalesce() or nvl():
where COMPANY_ID = coalesce(:P11_FILTER, COMPANY_ID)
coalesce(:P11_FILTER, COMPANY_ID) returns COMPANY_ID when :P11_FILTER is null.
Note that this where clause does not match in the situation where both COMPANY_ID and the parameter are NULL. This is different from the OR solution, that would returns the NULL row here.
One method uses or:
where COMPANY_ID = :P11_FILTER or :P11_FILTER is null

Grouping and null values in column

Need some help in how to fix a problem.
Below is my input data. Here I am doing a group by based on name field. The query which I am currently used for grouping is given below.
select name from Table
group by name having count(distinct DOB)='1'
But the problem is that the above query won't fecth records if the DOB field is null for all records within a group.In case if I try to give some dummy value for DOB field, then It won't fetch the result for first two rows and if I didn't give the dummy value for it won't fecth the records in 3 and 4
I tried something like this, but it is wrong
select name from Table
group by name having count(distinct case when DOB is null then '9999-01-01' else DOB END)='1'
Could someone help here with some suggestions. My expected result is given below.
You can replace the logic with:
having min(dob) = max(dob) or
min(dob) is null
Depending on your data, count(distinct) can be relatively expensive, so this can actually be cheaper than using it.
You can use count(distinct). Just change the comparison value:
having count(distinct dob) <= 1

get data for users with properties not present in all rows -sql

My data has orderid, userid and userage along with a lot other data.
Now age is something that the user can provide if and whenever he/she wishes.
Sample data
orderid userid userage
1 1
2 2
3 1
4 1 18
5 3 25
Now, if I wish to find all orderids for userage=18, I can not do something as Select orderid from table where userage=18 as it will give me only orderid '4'.
I want a single query which should preferably work on any db (as though I'm using sql server, it might change any time) which will give me result which has orderid '1', '3' and '4'.
Thanks
I think you are asking for all orderid where the userid has a userage value of 18.
In which case the following should work:
SELECT orderid
FROM TABLE
WHERE userid IN (SELECT DISTINCT userid
FROM TABLE
WHERE userage = 18)
You haven't disclosed how you represent missing data. Many DBMS designs use NULL values for that. If that's your situation
SELECT orderid FROM table WHERE (userage = 18 OR userage IS NULL)
will work.
If you use -1 for missing data (you probably don't, but I'm trying to make a point here)
SELECT orderid FROM table WHERE (userage = 18 OR userage = -1)
will work.
Notice that when a column value is NULL, no test for equality or inequality ever comes back true. You must is IS NULL or IS NOT NULL to test NULLs.
In Oracle, zero length text strings are NULL. That's not so in other DBMSs.
If you're looking for all orders from a user who has ever given an age of 18, this will do the trick
SELECT orderid
FROM table
WHERE userid IN (SELECT userid FROM table where userage = 18)
Please try this:
Select orderid from table where orderid in (1,3,8)

DISTINCT ON column only for non null values

How should I declare a query to only use DISTINCT on not null values for certain column but still keep the records for which the column value is null, I'm trying to modify the following query:
I'm trying to modify the following query,
So, basically I want the second query to return all the messages grouped by parent_id when the parent_id column IS NOT NULL and return ALL the records when parent_id IS NULL.
I'm using PG 9.0.4 and Rails 3.1 - any help would be appreciated, thanks!
Select Distinct ON (parent_id) *
from messages
WHERE parent_id IS NOT NULL
UNION
Select * from messages where parent_id IS NULL