SQL if statement debugging - sql

I have the following two queries, The first one works as you would expect. The second raises an exception saying invalid column name ISDELETED. BUT I've added the if else structure precisely to avoid that error, what am i doing wrong On the second query
IF COL_LENGTH('vwAs', 'IsActive') IS NOT NULL
select 1
ELSE IF COL_LENGTH('vwABCs', 'IsDeleted') IS NOT NULL
select 0
ELSE SELECT -1
And
IF COL_LENGTH('vwAs', 'IsActive') IS NOT NULL
select Count(*) [vwB] from [vwAs] WHERE ISACTIVE = 1
ELSE IF COL_LENGTH('vwABCs', 'IsDeleted') IS NOT NULL
select Count(*) [vwABCsActive] from [vwABCs] WHERE ISDELETED = 0
ELSE SELECT -1

Before run the query DB Engine try to validate your code, but not validate your logic. If your table hasn't ISDELETED column DB shows you an error. So you have to hide from DB Engine your wrong code as dynamic sql. Dynamic sql will not be validate.
IF COL_LENGTH('vwAs', 'IsActive') IS NOT NULL
select Count(*) [vwB] from [vwAs] WHERE ISACTIVE = 1
ELSE IF COL_LENGTH('vwABCs', 'IsDeleted') IS NOT NULL
exec('select Count(*) [vwABCsActive] from [vwABCs] WHERE ISDELETED = 0')
ELSE SELECT -1

Related

WHERE from CASE result

I have a statement - simplified
SELECT UserID,
CASE WHEN UserName = 'xxx' THEN 1 ELSE 0 AS Deleted
FROM User
WHERE Deleted = 0;
but this doesn't work because Deleted can't be used.
Is there a workaround? I can't solve it this way WHERE UserName <> 'xxx' , because in my real statement it's a huge sub select.
Wrap your original query up in a derived table. (Since column aliases aren't available in the same query's where clause.)
select *
from
(
SELECT UserID,
CASE WHEN UserName = 'xxx' THEN 1 ELSE 0 END AS Deleted
FROM User
) dt
WHERE dt.Deleted = 0;
We can use like below without sub queries.
SELECT *
FROM [User]
WHERE (CASE WHEN UserName = 'xxx' THEN 1 ELSE 0 END)=0

How to check if all rows validate a predicate

I've a table in my database for which I need to check if all rows have one field not null.
If there are no row or if there is at least 1 row with the field null => true
If there are rows and they are all with the field not null => False
Is there a way to do this in on simple query? Or I need to check if my table is empty first then if it's not check if I've a row with the field value empty ?
This will count how many NULL values you have in a field;
SELECT
SUM(CASE WHEN FieldName IS NULL THEN 1 ELSE 0 END) NullValues
FROM TableName
Will return 0 if there are no NULL values, and will return the number of NULLS if there are any present.
If you actually want to return a value as 'True' or 'False' then do this;
SELECT CASE
WHEN a.NullValues > 0
THEN 'True'
ELSE 'False'
END CheckField
FROM (
SELECT
SUM(CASE WHEN FieldName IS NULL
THEN 1
ELSE 0
END) NullValues
FROM TableName
) a
Use count(*) and count(field) and compare the two:
select
case when count(*) > 0 and count(*) = count(field) then 1 -- not empty and no nulls
else 0 end as isgood
from mytable;
Oracle SQL has no boolean data type , so I use 1 for true and 0 for false. You can replace this with whatever you like (e.g. 'true' instead of 1 and 'false' instead of 0).
As to turning this into a predicate (correlated to a main query), you'd use something along the lines of:
select ...
from main
where exists
(
select 1
from mytable
where mytable.colx = main.coly
having count(*) > 0 and count(*) = count(field)
);
You can do this with aggregation. However, it is difficult to understand what you are asking for. If you want to check that a field has no NULL values, you can do:
select (case when count(*) > 0 then 1 else 0 end) as HasNullValues
from t
where field is null;
Alternate way I found using max with putting null first:
select case when
max(field) keep (dense_rank first order by datfin desc nulls first) is null then 1
else 0 end as flag
from MYTABLE;

Return an INT from a Case statement

I am attempting to create a row called Flag that will keep a count of when Value is above 2. Later I will need to sum flag as a count.
I currently have:
CASE
WHEN Value > 2
THEN 1
ELSE 0
END AS 'Flag',
CASE
WHEN 'Flag' = 1
THEN 1
ELSE 0
END AS 'FollowedUpCorrectly'
I receive the error:
Conversion failed when converting the varchar value 'Flag' to data
type int.
How can I force the 1 or 0 to be an INT in order to do later math?
I've looked around and I can't seem to find a way that fits.
To be able to use previously created columns in the select, you'll need to use for example outer apply, with something like this:
select
*
from table1
outer apply (
select CASE WHEN Value > 2 THEN 1 ELSE 0 END AS Flag
) X
outer apply (
select CASE WHEN X.Flag = 1 THEN 1 ELSE 0 END AS FollowedUpCorrectly
) Y
Test this in SQL Fiddle
You could use CTE or a subquery to create a flag and then do your case statement as needed in the outer query like this:
;WITH q1
AS (
SELECT
col1
,col2
,col3
,CASE
WHEN Value > 2
THEN 1
ELSE 0
END AS 'Flag'
FROM your_table --change this to match your table and column name
)
SELECT q1.col1
,q1.col2
,q1.col3
,CASE
WHEN q1.Flag = 1
THEN 1
ELSE 0
END AS 'FollowedUpCorrectly'
FROM q1;
I might misunderstand what you are after.
CASE
WHEN Value > 2
THEN 1
ELSE 0
END AS 'Flag',
CASE
WHEN 'Flag' = 1
THEN 1
ELSE 0
END AS 'FollowedUpCorrectly'
If these two lines are in the same code block, 'Flag' is unknown in the second Case Statement.
Update: As Siyual has pointed out, Flag is a string literal. Try changing the name to something that is not a reserved word.
You are comparing a string ('Flag') to an int (1). Perhaps you meant to refer to the first case that you named 'Flag'. If so, try referring to it without using the single quotes. Then the analyzer will recognize it and accept it as an int, which it is. But 'Flag' is a string. Flag is an int.

SQL, Select if or select case

I am not sure what I am trying is achievable or not!!
I am trying to write a SQL query will will do select statement based on user input.
so if user input = 1 then I want it to select from actual table.
if user input = 0 then I want it do select 0 or null from dual. (if this is possible).
so Here is Parameter which will used to get input from user. ?i_userkey:'':null?
if user input's 1 then it will change null to 1.
I want to write a query using this parameter. something like this.
below is the logic.
IF i_userkey = 1 then
select ID,Gender,Age from TableA
If i_userkey = 0 then
select 0 or null from dual.
is this possible?
How about this:
SELECT
CASE WHEN i_userkey = 1 THEN ID ELSE NULL END AS ID
CASE WHEN i_userkey = 1 THEN Gender ELSE NULL END AS Gender
CASE WHEN i_userkey = 1 THEN AGE ELSE NULL END AS Age
FROM TableA
This will at least give you a consistent three-column result set you can work with. Having the query return differing column counts is not going to work.
select ID,Gender,Age
from TableA
where i_userkey = 1
union all
select 0, 0, 0
from dual
where i_userkey = 0
You might have to adjust the datatypes in the dual-select to match TableA

<> operator in SQL

I have a table like this
ID Name IsDeleted
1 Yogesh Null
2 Goldy 1
Now when I run this query
select *
from tableName
where IsDeleted <> 1
I should get ID 1 record, But I am not getting it,
But when I run this
select *
from tableName
where IsDeleted is null
I get ID 1 record,
Why am I facing this behavior ??
Isn't NULL <> 1 is a true statement in SQL ??
IsDeleted is a bit type field with Allow Null true
select * from table
where COALESCE(IsDeleted, 0) <> 1
-- or ISNULL instead of COALESCE.
--ISNULL seems to be better in subqueries, but it's not ANSI SQL.
or
select * from table
where IsDeleted <> 1 or IsDeleted IS NULL
Comparing something with null will always result in unknown. That is why you need to use the is operator to compare null or use functions like COALESCE or isnull to replace null
select *
from tableName
where isnull(IsDeleted,0) <> 1
you compare different types. in this case its an other type (unknown) and not comparable
use the or statement to compare each type seperate
WHERE IsDeleted <> 1 OR IsDeleted is null
Learn about NULL - a comparison with NULL (in standard SQL) yields UNKNOWN, which is not true nor false (and the reason why your expectation is not met).
Try this:
PRINT CASE
WHEN 1 = NULL THEN '1 = NULL'
WHEN 1 <> NULL THEN '1 <> NULL'
ELSE '1 is neither = NULL nor <> NULL'
END
You can either first make sure that you don't have a NULL value (for instance by using the ISNULL or COALESCE functions), or use a condition with the operator IS NULL or IS NOT NULL.
Normal practice would dictate that if you had a column that essentially was a true false, yes no type of field then you should use a bit field with the default value set to 0.
So in your case above you could just run this:
select *
from tableName
where IsDeleted = 0
But in answer to your above question, if the Null is a true NULL value in the table then this will work for you:
select *
from tableName
where IsDeleted is null
or
select *
from tableName
where isnull(IsDeleted,0) = 0
to get record 1 and
select *
from tableName
where IsDeleted is not null
to get record 2
Good luck
Paul.