Query SQL Server with IN (NULL) not working - sql

When I define a "User-Defined Table Type", as:
CREATE TYPE [dbo].[BitType] AS TABLE(
[B] [bit] NULL
)
I place 0 and null in this table-variable.
Then I do this query:
SELECT something FROM theTable WHERE item IN #theBitTypeTable
Will only get item=0 not item is null
Simply put: SELECT something FROM theTable WHERE item IN (0, NULL) is not working (no error although)
It has to be SELECT something FROM theTable WHERE item=0 OR item IS NULL
So, my question is, if I like to use User-Defined Table Type, but I also need to use NULL value. How can I perform the query correctly to get result include null item.
Thanks (btw, I use MS SQL Server 2008 R2)

The only valid comparison operations with NULL values are IS NULL or IS NOT NULL, others always return false (actually - Unknown, see the #Damien_The_Unbeliever's comment)
So, try the following
CREATE TYPE [dbo].[BitType] AS TABLE(
[B] [tinyint] NOT NULL
)
GO
declare #theBitTypeTable BitType
insert #theBitTypeTable
VALUES(0), (2 /* instead of NULL*/)
SELECT something FROM theTable WHERE IsNull(cast(item as tinyint), 2) IN (select B from #theBitTypeTable)

Null does not equal null in SQL Server (and most other database management systems). You would need to do a coalesce on the joined column, and use a sentinel value to represent nulls.

There is a cheat use isnull on the item being compared.
eg
SELECT something
FROM theTable
WHERE ISNULL(item,0) IN (0)

Related

mismatch not picked up when one value is null

I have a simple SQL query where a comparison is done between two tables for mismatching value.
Yesterday, we picked up an issue where one field was null and the other wasn't, but a mismatch was not detected.
As far as I can determine,the logic has been working all along until yesterday.
Here is the logic of the SQL:
CREATE TABLE Table1
(UserID INT,PlayDate DATETIME)
CREATE TABLE Table2
(UserID INT,PlayDate DATETIME)
INSERT INTO Table1 (UserID)
SELECT 5346
INSERT INTO Table2 (UserID,PlayDate)
SELECT 5346,'2012-11-01'
SELECT a.UserID
FROM Table1 a
INNER JOIN
Table2 b
ON a.UserID = b.UserID
WHERE a.PlayDate <> b.PlayDate
No values are returned even though the PlayDate values are different.
I have now updated the WHERE to read:
WHERE ISNULL(a.PlayDate,'') <> ISNULL(b.PlayDate,'')
Is there a setting in SQL which someone could have changed to cause the original code to no longer pick up the difference in fields?
Thanks
NULL <> anything
is unknown not true. SQL uses three valued logic (false/true/unknown) and the predicate needs to evaluate to true in a where clause for the row to be returned.
In fact in standard SQL any comparison with NULL except for IS [NOT] NULL yields unknown. Including WHERE NULL = NULL
You don't state RDBMS but if it supports IS DISTINCT FROM you could use that or if you are using MySQL it has a null safe equality operator <=> you could negate.
You say you think it previously behaved differently. If you are on SQL Server you might be using a different setting for ANSI_NULLS somehow but this setting is deprecated and you should rewrite any code that depends on it anyway.
You can simulate IS DISTINCT FROM in SQL Server with WHERE EXISTS (SELECT a.PlayDate EXCEPT SELECT b.PlayDate)
Not even a NULL can be equal to NULL.
Here are two common queries that just don’t work:
select * from table where column = null;
select * from table where column <> null;
there is no concept of equality or inequality, greater than or less
than with NULLs. Instead, one can only say “is” or “is not”
(without the word “equal”) when discussing NULLs.
- The correct way to write the queries
select * from table where column IS NULL;
select * from table where column IS NOT NULL;

Oracle SQL Case statement with NULL values

I'm trying to create an Oracle query that will use a parameter based on the CommandName of a button.
So here's my query
SELECT id
FROM table
WHERE dateTime IS (CASE WHEN :CommandName = 'FIRST' THEN NULL ELSE NOT NULL END)
So I'm passing the parameter but it's not working - I'm just getting a Missing NULL keyword error
I basically don't want to have to write two separate queries based on the parameter that is input
Not even sure if this is possible or if this is the right way of doing it?
Any ideas?
You may want to read up on the CASE statement a bit more.
I believe you want the following code:
SELECT
id
FROM
table
WHERE
(
(dateTime IS NULL AND :CommandName = 'FIRST')
OR
(dateTime IS NOT NULL AND NVL(:CommandName, '') <> 'FIRST')
)
Without using dynamic SQL to return the string 'NULL' or 'NOT NULL' you could use two NVL() functions:
select id
from table
where NVL(dateTime,'FIRST') = NVL(:param,dateTime);
However, if dateTime is indexed (and Oracle can index NULLs), ths NVL() function will disable the index.
I think that
SELECT id
FROM table
WHERE (dateTime IS NULL AND :CommandName='FIRST') OR (dateTime IS NOT NULL AND :CommandName <> 'FIRST')
should do what you need.

Null Value Statement

I have created a table called table1 and it has 4 columns named Name,ID,Description and Date.
I have created them like Name varchar(50) null, ID int null,Description varchar(50) null, Date datetime null
I have inserted a record into the table1 having ID and Description values. So Now my table1 looks like this:
Name ID Description Date
Null 1 First Null
One of them asked me to modify the table such a way that The columns Name and Date should have Null values instead of Text Null. I don't know what is the difference between those
I mean can anyone explain me the difference between these select statements:
SELECT * FROM TABLE1
WHERE NAME IS NULL
SELECT * FROM TABLE1
WHERE NAME = 'NULL'
SELECT * FROM TABLE1
WHERE NAME = ' '
Can anyone explain me?
In a CREATE TABLE, the NULL or NOT NULL here varchar(50) null is a constraint that determines whether NULLs are allowed. NOT NULL means no.
When you inserted data, which statement did you run?
INSERT TABLE1 VALUES (Null, 1, First, Null)
or
INSERT TABLE1 VALUES ('Null', 1, First, 'Null')
The first one uses the keyword NULL, inserts a NULL (not a null value: no such thing, arguably). No values is stored except in the NULL bitmap fields
The second one has a string "null" and the characters N, U, L, L + 2 bytes for length are stored
When you run SELECT * FROM TABLE1, client tools will show NULL.
To test whether you actually have NULLs or the string NULL, run this
SELECT ISNULL(name, 'fish'), ISNULL(date, GETDATE()) FROM TABLE1
For the SELECTs
--null symbols. No value stored
SELECT * FROM TABLE1 WHERE NAME IS NULL
--string null
SELECT * FROM TABLE1 WHERE NAME = 'NULL'
--empty string
SELECT * FROM TABLE1 WHERE NAME = ' '
Note: null symbol/value is not empty string. It has no value and won't compare. Even to itself.
As for your DBA, the code above with ISNULL will decide what is stored.
Edit: if you are storing null symbol/value, then your DBA should read up on "null bitmap"
The data does represent nulls. The text 'Null' is your query tool displaying the text.
One of them asked me to modify the table such a way that The columns Name and Date should have Null values instead of Text Null. I don't know what is the difference between those.
The NULL keyword indicates the absence of any value -- the value is unknown.
But that won't stop someone from storing the letters that spell out "NULL", data type providing (which INT and DATETIME will not). Because of this, operators like IS NULL would not work on text that spells out "NULL" and vice versa -- searching for strings using: ... LIKE '%NULL%' will not return records with NULL values.
The data type of the column does matter with regard to NULL in SQL Server. In a UNION statement, you need to cast NULL to be the appropriate data type -- the default for NULL is INT:
SELECT CAST('2011-01-01 00:00:00' AS DATETIME)
UNION
SELECT CAST(NULL AS DATETIME)
Based on the information provided about the columns and the output, the DBA appears to be asking you to change the text the client you are using to connect to SQL Server with displays when a NULL value is encountered in a resultset. Reminds me of my first job dishwashing, and was asked to get the lefthanded spatula...
The string "Null" is a string.
The value of NULL (or Null or null, SQL is case-insensitive when it comes to these things) is used to denote an unknown value. It's the empty set of values, if you will.
http://www.w3schools.com/sql/sql_null_values.asp
NULL, in software, is symbolic of no value. Assuming you're inserting the columns using a string with null as the value, use the null constant. e.g.
INSERT INTO table1 (Name,ID,Description,Date) VALUES (NULL,1,'First',NULL);
Note that NULL is a constant in SQL, not the word "NULL" in a string.
AFAIC, there is no different between NULLs. There are different column types. But as long as a column is a text data type, and it's NULL, it's a text NULL.
Sometimes there are questions about empty strings ("") instead of NULLs, but the description you're using doesn't seem to be referring to that.
SELECT * FROM TABLE1 WHERE NAME IS NULL
Returns all rows where the Name is NULL
SELECT * FROM TABLE1 WHERE NAME = 'NULL'
Returns all rows where the Name is equal to the string 'NULL', Null values are not returned
SELECT * FROM TABLE1 WHERE NAME = ' '
Returns all rows where the Name is equal to exactly one space ' ', Null values are not returned
If you run this statement it might help clear up when its null and when its not
select
*,
case
WHEN name is null THEN 'Its Null alright'
ELSE 'It has a value'
END
FROM TABLE1

Select rows where column is null

How do you write a SELECT statement that only returns rows where the value for a certain column is null?
Do you mean something like:
SELECT COLUMN1, COLUMN2 FROM MY_TABLE WHERE COLUMN1 = 'Value' OR COLUMN1 IS NULL
?
I'm not sure if this answers your question, but using the IS NULL construct, you can test whether any given scalar expression is NULL:
SELECT * FROM customers WHERE first_name IS NULL
On MS SQL Server, the ISNULL() function returns the first argument if it's not NULL, otherwise it returns the second. You can effectively use this to make sure a query always yields a value instead of NULL, e.g.:
SELECT ISNULL(column1, 'No value found') FROM mytable WHERE column2 = 23
Other DBMSes have similar functionality available.
If you want to know whether a column can be null (i.e., is defined to be nullable), without querying for actual data, you should look into information_schema.
Use Is Null
select * from tblName where clmnName is null
You want to know if the column is null
select * from foo where bar is null
If you want to check for some value not equal to something and the column also contains null values you will not get the columns with null in it
does not work:
select * from foo where bar <> 'value'
does work:
select * from foo where bar <> 'value' or bar is null
in Oracle (don't know on other DBMS) some people use this
select * from foo where NVL(bar,'n/a') <> 'value'
if I read the answer from tdammers correctly then in MS SQL Server this is like that
select * from foo where ISNULL(bar,'n/a') <> 'value'
in my opinion it is a bit of a hack and the moment 'value' becomes a variable the statement tends to become buggy if the variable contains 'n/a'.
select Column from Table where Column is null;
select * from tableName where columnName is null
For some reasons IS NULL may not work with some column data type. I was in need to get all the employees that their English full name is missing, I've used:
SELECT emp_id, Full_Name_Ar, Full_Name_En
FROM employees
WHERE Full_Name_En = '' or Full_Name_En is null

How to alter the boolean value in SQL Server select query?

Basically I want to alter the boolean value selecting from the table:
e.g.:
SELECT otherColumns, not ysnPending FROM table
I need a column ysnPending = true if the value is false & false if the value is true.
Is there any function available to alter the Boolean value or I should use IIf or CASE...?
use CASE, or if the bit field is non-nullable you could just subtract from 1.
SELECT
otherColumns,
(1 - ysnPending) -- NOT ysnPending
FROM table
(Using CASE might lead to more understandable code.)
If ysnPending is nullable, what behaviour do you assign to NOT?
Example using a case statement :
create table table1 (id int not null, ysnPending bit null)
insert table1 values (1, 1)
insert table1 values (2, null)
insert table1 values (3, 0)
select id, cast((case when ysnPending = 1 then 0 else 1 end) as bit) as Not_ysnPending from table1
Assumes you want 1 returned when ysnPending is NULL.
The cast to bit type is to make sure that the returned column is of a BIT datatype. If you leave it out, it will return an INTEGER type. (This may or may not matter to you, depending on how exactly you are going to use the returned result set).