CASE statement with IN in WHERE clause - sql

I'm trying to create the following WHERE clause:
AND CASE #SomePRarmeter
WHEN 'this' THEN
user_id IN (SELECT * FROM dbo.func_Id1(#User))
WHEN 'that' THEN
user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter)
END
But I'm getting an error: Incorrect syntax near the keyword 'IN' (in the first condition) , although separately both of those conditions work. What would be the correct way to make such a statement work?
Thanks!

Try
AND (
(#SomePRarmeter = 'this' AND user_id IN (SELECT * FROM dbo.func_Id1(#User)))
OR
(#SomePRarmeter = 'that' AND user_id IN user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter)))
)

You are doing select * in a subquery. You need to return only one column:
(SELECT * FROM dbo.func_Id1(#User))
to this:
(SELECT YOUR_USER_ID_COLUMN FROM dbo.func_Id1(#User))

A case statement must result in a value, not an expression. So this won't work:
select case when 1=1 then 1 in (1,2,3) end
But this will work;
select case when 1=1 then 1 end
The value can be the result of a subquery. So one solution would be to rewrite the where clause like:
CASE #SomePRarmeter
WHEN 'this' THEN
(SELECT count() FROM dbo.func_Id1(#User) f where f.user_id = t.user_id))
WHEN 'that' THEN
(SELECT count() from dbo.func_Ids2(#OrgsForReporter) f where f.user_id = t.user_id))
END > 1
Now it returns the number of matching rows. You can then filter with case ... end > 1.

I'd break this out:
IF 'this'
SELECT
...
WHERE user_id IN (SELECT * FROM dbo.func_Id1(#User))
ELSE IF 'that'
SELECT
...
WHERE user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter))

CASE ... END returns an expression, not a piece of literal SQL code. Rather than:
AND CASE foo WHEN bar THEN bla=ble END -- Wrong
... you have to use this:
AND bla = CASE foo WHEN bar THEN ble END -- Right
In your case, you can do something on this line:
-- Untested
AND (
(#SomePRarmeter='this' AND user_id IN (SELECT * FROM dbo.func_Id1(#User)))
OR (#SomePRarmeter='that' AND user_id IN (SELECT user_id from bo.func_Ids2(#OrgsForReporter))
)

Related

Returning something like error-codes from query

I want to check conditions in query. If condition is false, then query must returns error code, else query must to execute another query.
Something like that:
WITH error_code_get AS (
SELECT
CASE
WHEN NOT EXISTS (
SELECT 1
FROM users
WHERE id = '1a4b...'
) THEN 1
WHEN NOT EXISTS (
SELECT 1
FROM workspaces
WHERE id = '353...'
) THEN 2
WHEN (
SELECT settings
FROM workspace_roles
WHERE workspace_id = '353...'
AND id IN (
SELECT role_id
FROM m2m_users_to_workspace_or_projects_roles
WHERE role_type='1'
AND user_id='1a4b...'
)
) < 2 THEN 3
ELSE 0
END error_code
RETURNING error_code
)
// WRONG PART
CASE
WHEN (SELECT error_code FROM error_code_get) = 0 THEN (INSERT INTO x(a) VALUES('some_value'))
ELSE (SELECT error_code FROM error_code_get)
END
You can't do something like that in pure SQL, you'd need to write code in Stored Proc or Function

COUNT vs SELECT in SQL

What is better approach to check existence of an object in database?
select count(id) as count from my_table where name="searchedName";
OR
select id from my_table where name="searchedName";
And then check if count > 0 or the object is not null (ORM logic)
EDIT:
select id to be valid for Oracle.
The idea should be to that we only need to find one record in order to say that such record exists. This can be done with an EXISTS clause in standard SQL.
select exists (select * from mytable where name = 'searchedName');
returns true if the table contains a record with 'searchedName' and false otherwise.
If you want 0 for false and 1 for true instead (e.g. if the DBMS does not support booleans):
select case when exists (select * from mytable where name = 'searchedName')
then 1 else 0 end as does_exist;
You say you want this for Oracle. In Oracle you can use above query, but you'd have to select from the table dual:
select case when exists (select * from mytable where name = 'searchedName')
then 1 else 0 end as does_exist
from dual;
But for Oracle we'd usually use rownum instead:
select count(*) as does_exist
from mytable
where name = 'searchedName'
and rownum = 1; -- to find one record suffices and we'd stop then
This also returns 1 if the table contains a record with 'searchedName' and 0 otherwise. This is a very typical way in Oracle to limit lookups and the query is very readable (in my opinion).
I'd just call:
select id from my_table where name='searchedName';
Making sure there is an index for the name column.
And then check whether or not the result is empty.
Try with IF EXISTS (
if exists (select 1 from my_table where name = "searchedName")
begin
....
end

single query that defines 2 tables has same row

query 1
(select count(*) from CALENDAR)
it returns 15
query 2
(select value from PARAMETER where name = 'PLAN_HORIZON')
it returns 15 too only when my programs runs without error. if error occurs,
it returns 10 or other values.
this↓ is wrong sql, but i want a single query which returns True or False.
select if (query1 == query2)
How can I define 2 sql has same result in a query?
The following SQL statement returns 0 or 1. It runs with SQL Server
SELECT CASE WHEN (select count(*) from CALENDAR) = (select value from PARAMETER where name = 'PLAN_HORIZON') THEN 1 ELSE 0 END
Something like this:
select count(*) = 0
from (
select count(*)
from calendar
except
select value
from parameter
where name = 'PLAN_HORIZON'
) t
You didn't specify your DBMS, but the above is standard SQL.
Try this query !
SELECT
CASE
WHEN (select count(*) from CALENDAR) = (select value from PARAMETER
where name = 'PLAN_HORIZON')
THEN true
ELSE false
END ;

nvl with query inside

Its possible to do something like this:
and zmt.mediatypeid in nvl(:P21_MEDIA, select mediatypeid from zbx.media_type)
:P21_MEDIA is a variable
Yes, it is called a scalar subquery expression:
select x, (select y from another_table where foo = x) from the_table
select x from the_table where foo = (select y from another_table where bar = x)
It can only return a single column and a single row, anything else is an error.
I cannot test it right now, but I would assume you can also use it inside a function such as NVL. The documentation only mentions that it cannot be used in GROUP BY.
yes, you can use CASE statement to check the condition:
and 1 = CASE
WHEN :P21_MEDIA IS NOT NULL THEN
CASE
WHEN zmt.mediatypeid = :P21_MEDIA THEN 1
ELSE 0
END
WHEN zmt.mediatypeid IN (select mediatypeid from zbx.media_type) THEN 1
ELSE 0
END

Referring to results of a sub query in main query

I have a sub query that returns one column, showing as GroupType, I then want to do a CASE function on this result within the main query, however I get an invalid column name when using the CASE statement.
Can i do this in SQL to do I have to refer to it by a different name
SELECT CASE
WHEN
(
SELECT column
FROM othertable
) = 1
THEN '1'
ELSE '2'
END
FROM mytable
To reuse the subquery result:
SELECT subvalue, CASE subvalue WHEN 1 THEN 1 ELSE 2 END
FROM (
SELECT (
SELECT column
FROM othertable
) AS subvalue
FROM mytable
) q