WHERE from CASE result - sql

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

Related

Use a CASE expression Column value in another CASE expression in SQL Query

I am trying to user one column obtained from the CASE expression to SET another Column Value.
E.G. I have a table user with multiple column. First, I need to set the status of a project based on the values of some columns in the table. I am able to make this part work. The second part is, based on the status value, I need to get the user name(s) from multiple columns. When I do that, am getting an error
Invalid Column 'Status'
A sample query follows:
SELECT
STATUS = CASE WHEN ISNULL(USER1,'') = '1' THEN 'Approve'
WHEN ISNULL(USER2,'') = '2' THEN 'Reject'
WHEN ISNULL(USER3,'') = '3' THEN 'Pending Decision'
ELSE 'error' END,
USERNAME = CASE WHEN ISNULL(STATUS,'') = 'Approve' THEN (select username1 from <table> where userid = <userid>)
WHEN ISNULL(STATUS,'') = 'Reject' THEN (select username2 from <table> where userid = <userid>)
WHEN ISNULL(STATUS,'') = 'Pending Decision' THEN (select username3 from <table> where userid = <userid>)
ELSE 'error' END
from <table> where userid = <userid>
You can't reuse an expression defined in the select clause in the same clause.
I don't really see why you need the value returned by the first expression to compute the second value, since the logic is basically the same.
You can just do:
select
case
when user1 = 1 then then 'Approve'
when user2 = 2 then 'Reject'
when user3 = 3 then 'Pending Decision'
else 'error'
end status,
case
when user1 = 1 then (select username1 from <table> where userid = <userid>)
when user2 = 2 then (select username2 from <table> where userid = <userid>)
when user3 = 3 then (select username3 from <table> where userid = <userid>)
end username
from <table> where userid = <userid>
Notes
isnull() is unnecessary, since the alternative value is not trapped anywhere in the case statement
this treats user1 as a number, because it looks like it - so I unquoted the test values in the case statement. If it's actually a string, you can revert this and add the single quotes.
I am quite suspicious about the logic of the subqueries; there might be ways to simplify that, if you were to provide more details on what they are intented to do, along with sample data and desired results.
This works, because #status will be processed before username
And you have to use user defined variables, you can't use columnnames for that
SELECT
#status := (CASE WHEN COALESCE(USER1,'') = '1' THEN 'Approve'
WHEN COALESCE(USER2,'') = '2' THEN 'Reject'
WHEN COALESCE(USER3,'') = '3' THEN 'Pending Decision'
ELSE 'error' END) `STATUS`
,
CASE WHEN COALESCE(#status,'') = 'Approve' THEN (select username1 from table1 where userid = 20)
WHEN COALESCE(#status,'') = 'Reject' THEN (select username2 from table1 where userid = 20)
WHEN COALESCE(#status,'') = 'Pending Decision' THEN (select username3 from table1 where userid = 20)
ELSE 'error' END USERNAME
from table1 where userid = 20
You can use a "table expression" to pre-compute a column. For example:
select
*,
-- use the pre-computed STATUS column now
from (
SELECT *,
<CASE-expression> as status
from <table> where userid = <userid>
) x

SQL - Select statements within case

How do I achieve this using SQL case statement?
select count(*) x from t_table where file_id = 310012;
if x<>0 : select distinct status from t_table where file_id = 310012
else : return x
See the code below:
SELECT CASE COUNT(*)
WHEN COUNT(*) > 0 THEN
(SELECT status FROM t_table WHERE file_id = 310012)
ELSE null END AS x
FROM t_table WHERE file_id = 310012;
You can do what you want with a union all:
select distinct status
from t_table
where file_id = 310012
union all
select 0
from dual
where not exists (select 1 from t_table where tile_id = 320023);
However, returning a single row with 0 seems like a bad idea, because it could be confused with a value status.
Note: You should use '0' if status is a string.
You don't need to count records. Just do only one query:
select distinct status from t_table where file_id = 310012
When the query return some rows, then x must be <> 0
If the query returns an empty resultset, then x must be equal to 0, and you get the second part of if x <> 0 then ..... else return x
As a bonus you get a higher processing speed, because you run only one query against the table, not two.

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

SQL if statement debugging

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

Return Boolean Value on SQL Select Statement

How to return a boolean value on SQL Select Statement?
I tried this code:
SELECT CAST(1 AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)
And it only returns TRUE if the UserID exists on the table. I want it to return FALSE if the UserID doesn't exist on the table.
What you have there will return no row at all if the user doesn't exist. Here's what you need:
SELECT CASE WHEN EXISTS (
SELECT *
FROM [User]
WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
Possibly something along these lines:
SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM dummy WHERE id = 1;
http://sqlfiddle.com/#!3/5e555/1
Given that commonly 1 = true and 0 = false, all you need to do is count the number of rows, and cast to a boolean.
Hence, your posted code only needs a COUNT() function added:
SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)
Use 'Exists' which returns either 0 or 1.
The query will be like:
SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)
If count(*) = 0 returns false. If count(*) > 0 returns true.
I do it like this:
SELECT 1 FROM [dbo].[User] WHERE UserID = 20070022
Seeing as a boolean can never be null (at least in .NET), it should default to false or you can set it to that yourself if it's defaulting true. However 1 = true, so null = false, and no extra syntax.
Note: I use Dapper as my micro orm, I'd imagine ADO should work the same.
For those of you who are interested in getting the value adding a custom column name, this worked for me:
CAST(
CASE WHEN EXISTS (
SELECT *
FROM mytable
WHERE mytable.id = 1
)
THEN TRUE
ELSE FALSE
END AS bool)
AS "nameOfMyColumn"
You can skip the double quotes from the column name in case you're not interested in keeping the case sensitivity of the name (in some clients).
I slightly tweaked #Chad's answer for this.
Notice another equivalent problem: Creating an SQL query that returns (1) if the condition is satisfied and an empty result otherwise. Notice that a solution to this problem is more general and can easily be used with the above answers to achieve the question that you asked. Since this problem is more general, I am proving its solution in addition to the beautiful solutions presented above to your problem.
SELECT DISTINCT 1 AS Expr1
FROM [User]
WHERE (UserID = 20070022)
DECLARE #isAvailable BIT = 0;
IF EXISTS(SELECT 1 FROM [User] WHERE (UserID = 20070022))
BEGIN
SET #isAvailable = 1
END
initially isAvailable boolean value is set to 0