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

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).

Related

Strange query grouping in sqlite3

I have a table like this:
CREATE TABLE prices2
(
id_price integer primary key,
date text,
value real
);
And let's say I have this values:
insert into prices2( '01/01/2017', 1 );
insert into prices2( '02/01/2017', 2 );
insert into prices2( '02/01/2017', 3 );
insert into prices2( '04/01/2017', 7 );
insert into prices2( '04/01/2017', 6 );
I wonder why this select is correct and returns some results, and what is returning:
select date,
count(*)
from prices2
where date
group by date like '%/01/2017';
Maybe "date like "%/01/2017" is a boolean expression that returns some kind of value???
date like '%/01/2017' indeed is a boolean expression; in SQLite, it returns either 0 or 1:
> select date, date like '%/01/2017' from prices2;
01/01/2017|1
02/01/2017|1
02/01/2017|1
04/01/2017|1
04/01/2017|1
So when you use this expression in the GROUP BY clause, you get one group for 1 values, and one group each for 0 and NULL values (but there are none in this example).
As for where date, the documentation says:
The SQL language features several contexts where an expression is evaluated and the result converted to a boolean (true or false) value. These contexts are:
the WHERE clause of a SELECT, UPDATE or DELETE statement,
[...]
To convert the results of an SQL expression to a boolean value, SQLite first casts the result to a NUMERIC value in the same way as a CAST expression. A numeric zero value (integer value 0 or real value 0.0) is considered to be false. A NULL value is still NULL. All other values are considered true.
The date values begin with a number that is not zero, so they are interpreted as true.

Is a subquery, which is returning no row, equal to NULL?

In SQL Server, if my SELECT statement in a subquery returns no row, is then the result of the subquery equal to NULL? I made some research, but I am not sure about it.
Example:
IF (SELECT TOP 1 CLMN1 FROM SOMETABLE) IS NOT NULL THEN
....
I am asking to understand the behaviour of the if-statement above.
Looks like the answer is yes:
DECLARE #Test TABLE (Id INT)
INSERT INTO #Test VALUES (1)
SELECT * FROM #Test WHERE Id = 2
SELECT CASE WHEN (SELECT * FROM #Test WHERE Id = 2) IS NULL THEN 1 ELSE 0 END
EDIT: after you updated your question I think I should add that instead of checking if there are rows with IS NULL you should use the following that can be better optimised by the server:
IF EXISTS(SELECT * FROM #Test WHERE Id = 2)
BEGIN
-- Whatever
END
NULL means no value, for example that the "box" for a certain column in a certain row is empty. NO ROW means that there are no rows.
No, NULL is a column value that indicates that the value of that column for a given row has no valid value. There would have to be a row returned by your query for that row to contain NULL column values.
A query that returns no rows just means that no rows matched the predicate you used in the query and therefore no data was returned at all.
Edit: After the question was edited, my answer doesn't address the specific case called out in the question. Juan's answer above does.

Query SQL Server with IN (NULL) not working

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)

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

Why does the sql select statement fail?

In the scenario below, the final select from the Combine view fails, any ideas why?
The Subset table does not have a row that corresponds to the one in MasterCodes that wouldn't cast to an integer value.
CREATE TABLE MasterCodes (
ID INT
, Code VARCHAR(10) )
GO
CREATE TABLE Subset (
ID INT )
GO
CREATE VIEW Combine AS
SELECT S.ID
, M.Code
, CAST(M.Code AS INT) IntCode
FROM Subset S
INNER JOIN MasterCodes M ON M.ID = S.ID
GO
INSERT MasterCodes (ID, Code) VALUES (1, '1')
INSERT MasterCodes (ID, Code) VALUES (2, '2')
INSERT MasterCodes (ID, Code) VALUES (3, 'three')
INSERT MasterCodes (ID, Code) VALUES (4, '4')
INSERT Subset (ID) VALUES (1)
INSERT Subset (ID) VALUES (2)
INSERT Subset (ID) VALUES (4)
SELECT * FROM Combine -- 3 rows returned
SELECT * FROM Combine WHERE Code = '2' -- 1 row returned
SELECT * FROM Combine WHERE Code = '3' -- 0 rows returned
SELECT * FROM Combine WHERE IntCode = 2 -- fails, error msg is
Msg 245, Level 16, State 1, Line 15
Conversion failed when converting the varchar value 'three' to data type int.
Environment is Sql2k5 Standard (64-bit) ON Win2k3 Server R2
Probably because in some row, M.Code contains the literal word "three", and the view is trying to cast a non-numeric looking word into an int (you can probably cast "3" into an int, but not "puppy" or "three", etc.).
Edit: Added a comment, but worthwhile to add it here. SQL Server is going to try and execute and join the as efficiently as possible, and it's going try and apply the where clause apparently even before joining.
This makes sense if you consider that VIEWs nowadays work almost fully like a real table. It has to do something SIMILAR to this; otherwise, it will join everything and return all values BEFORE being filtered out.
Hideously expensive.
What I'm not sure about is if the execution plan will show this level of detail.
You're inserting the string "three" into MasterCodes.Code, and your view is attempting to cast this value to an integer. This SQL should give the same error:
select cast("three" as int)
Solution? Replace "three" with "3" in your insert statement.
Because when you try to use IntCode in your condition logic the view try's to cast "three" as an int.
Use isnumeric() with a case statement to create the view
case when isnumeric(field) then
cast(field as int)
else
null
end AS IntCode
If your result set is accurate:
"SELECT * FROM Combine WHERE Code = '2' -- 1 row returned
SELECT * FROM Combine WHERE Code = '3' -- 0 rows returned
SELECT * FROM Combine WHERE IntCode = 2 -- fails, error msg isMsg 245, Level 16, State 1, Line 15Conversion failed when converting the varchar value 'three' to data type int."
then the only time it fails is when you try to compare against IntCode field, it almost seems like it is failing when it tries to put the non-numeric value on the left side of the "IntCode = 2" comparison, because this is the only time it will need to pick up every single value in the code field.
Hope that helps!