SQL Conditional filter with different values - sql

I have found lots of posts on coniditonal filtering in the where clause, but they all seem to be based off of using the same value, such as:
WHERE (o.OrderID = #orderid OR #orderid IS NULL)
I need to do something slightly different, I need to remove a filter and its value completely base on another value, so something like:
select *
from tableA
where 1 = 1
case when a = 1 then
and b in (select b from tableB)
else
-- do nothing
end
I know that the above is not allowed, and I am just writing as an example of what I am trying to do. does Anyone have any idea of a good way to do this? I know i could use if statements and duplicate the query, but it is a large one, and i am trying to avoid that.
Thanks

SELECT *
FROM tableA
WHERE a <> 1
OR (a = 1 AND EXISTS(SELECT b from TableB WHERE tableA.b = TableB.b))
You could also write this as:
SELECT tableA.*
FROM tableA
LEFT JOIN tableB
ON tableA.b = tableB.b
WHERE tableA.a <> 1
OR (tableA.a = 1 AND tableB.b IS NOT NULL)

"Correcting" your WHERE clause:
select *
from tableA
where 'T' = case
when a = 1 then case
when b in (select b from tableB) then 'T'
end
else 'T'
end;

Related

SQL AND to see if two flags are set in two different tables?

SELECT 1 FROM
(SELECT 1 FROM mytable1 WHERE parentid = 'ID1' AND flag = 'Y') as X,
(SELECT 1 FROM mytable2 WHERE id = 'ID2' AND flag = 'Y') as Y
I'm making a query to see if two flags are set in two tables, where 'parentid' and 'id' are both primary keys. The query should return a row only if both flags are set to 'Y', or return nothing otherwise, then I do stuff with that result in my backend code.
I've tested this and it works but I feel like it looks wonky and could be optimized. Any ideas?
To get what You want:
SELECT 1
FROM mytable1 AS a, mytable2 AS b
WHERE a.parentid = 'ID1' AND a.flag = 'Y'
AND b.id = 'ID2' AND b.flag = 'Y'
But in fact, I would prefer a query with LEFT JOIN, which always gives one row, like this:
SELECT CASE WHEN a.flag = 'Y' AND b.flag = 'Y' THEN 1 ELSE 0 END AS result
FROM TABLE ( VALUES 1 ) AS always(present)
LEFT JOIN mytable1 AS a ON a.parentid = 'ID1'
LEFT JOIN mytable2 AS b ON b.id = 'ID2'
Your query is fine (although I would use CROSS JOIN. However, I would prefer a row with a specific value. I would phrase that as:
SELECT (CASE WHEN EXISTS (SELECT 1 FROM mytable1 WHERE parentid = 'ID1' AND flag = 'Y') AND
EXISTS (SELECT 1 FROM mytable2 WHERE id = 'ID2' AND flag = 'Y')
THEN 1 ELSE 0
END) as flag
You may need from dual, depending on your database.
It better to use JOIN instead of doing subqueries
SELECT mytable1.parentid, mytable2.id
FROM mytable1
JOIN mytable2 ON mytable2.flag = "Y" AND mytable1.flag = "Y"

using define to store the result of a select statement

Good evening, i want to ask about the feasibility of something so i have a select statement inside this select a lot of similare subqueries
i want to use a sub-query only once and store it's result I have tried something like that but I don't know what to do
any help would be appreciated
define A = Select somthing from TableA
Select case
when A <0
then 1
else 2
End as selectedcolumn from TableB
But i think that define is used only with static values
You can do this with a CTE, e.g.
WITH A AS
SELECT COUNT(*) c FROM TableA A
WHERE A.ColumnA = B.ColumnB
AND A.ColumnA2 = 0
Select A.c As test
from TableA ta
inner join TableB tb
on ta.columnA=tb.columnB
cross join A
This will make A.c available in your query. You can also then do (select c from A) anywhere in your query to get the value.
Alternately, if you're running a script in SQL*Plus, you can define a column variable using new_value:
COLUMN my_count NEW_VALUE my_constant
SELECT COUNT(*) my_count FROM TableA A
WHERE A.ColumnA = B.ColumnB
AND A.ColumnA2 = 0;
Then you can refer to it later on in your script using the substitution string &&my_constant:
Select case
when &&my_constant <0
then 1
else 2
End as selectedcolumn from TableB

Selective Join in View Sql

Here is pseudocode of what I am trying to achieve
Select * from TableA
if(TableA.criteria != 1)
inner join TableB.criteria = TableA.criteria
I must do it in view can use sp, functions, etc.
Thanks for any help you will be able to provide
Is this what you want?
Select a.*, b.* from TableA a join TableB b
on b.criteria = case when a.Criteria = 1
then 1 else null end
This may be what you want:
select a.*, b.*
from a left join
b
on b.criteria = a.criteria and b.criteria = 1;
The left join will keep all rows in a, even when the on condition is not true. The extra columns from b will be NULL, unless the criterias are both "1".

Update Field based on another table's values

Is there a more elegant way to write the following Microsoft SQL Server 2008 command?
UPDATE TableB
SET TableBField2=0
WHERE TableBID IN(
SELECT TableBID
FROM TableB
JOIN TableA on TableB.TableAID=TableA.TableAID
WHERE TableBField2 < 0
AND TableAField1 = 0
)
In plain speak, what I'm doing is updating a table based on the value of a field in a joined table. I wonder if my use of IN() is considered inefficient.
This should be more efficient:
UPDATE TableB b
SET TableBField2=0
WHERE exists (
SELECT 1
FROM TableA
WHERE b.TableAID=TableA.TableAID
AND b.TableBField2 < 0
AND TableAField1 = 0
)
You can try something like this
UPDATE TableB
SET Field2 = 0
FROM TableB b INNER JOIN
TableA a ON b.TableB.TableAID=a.TableAID
WHERE b.Field2 < 0
AND a.Field1 = 0

Can I join to a table in ORACLE (10g) using a CASE clause in the ON statement (or even where clause as it's an inner join)

I'm trying to make the following code smaller. Is this possible?
select a.*
from table1 a
WHERE a."cola1" = 'valuea1'
UNION ALL
select a.*
from tablea1 a
inner join tablea2 b on a."cola2" = b."colb2"
WHERE a."cola1" = 'valuea2'
and b."colb3" = 'valueb3'
In effect I'm looking for records from table1 for value1 or value2, but for records matching value2 I want to apply 1 extra condition which involves a join to a 2nd table
Can this be done without a UNION clause?
A skeleton or what I'm trying to code is below....but it's not working naturally.
select a.*
from table1 a
inner join table2 b on a."cola1" = b."COLb1"
WHERE a."cola2" IN ('valuea1','valuea2')
and
CASE
WHEN a."cola2" = 'valuea2' THEN b."colb1" = 'valueb3'
ELSE 1=1
END CASE
I think CASE statements work in join conditions, but I'm not sure. But would this work for you?
select *
from table1 a
where a.cola1 = 'valuea1'
or (a.cola1 = 'valuea2'
and Exists(select 1
from table2 b
where a.cola2 = b.colb2
and b.colb3 = 'valueb3'
)
)
Edit: Wouldn't this simply work?
select a.*
from table1 a
Left Outer Join table2 b On (a.cola2 = b.colb2)
where a.cola1 = 'valuea1'
or (a.cola1 = 'valuea2' and b.colb3 = 'valueb3')
Overall you should follow Hosam's suggestion of rewriting the predicate entirely. But to explain your original problem further, the issue is that in SQL, CASE .. END is an expression and can only be used where any other expression could be used. A condition like "a=b" is two expressions connected by a logical operator. You may want to think of it as a boolean expression but that's not the way SQL views it.
You could accomplish what you want with CASE by using it as one of the two expressions in the condition, like so:
WHERE a."cola2" IN ('valuea1','valuea2')
and
b."colb1" = CASE
WHEN a."cola2" = 'valuea2' THEN 'valueb3'
ELSE b."colb1"
END CASE
(If it is possible for colb1 to include NULLs you would need to modify to handle that.)
You can achieve this by using left join and where condition
select a.*
from table1 a
left join tablea2 b on a."cola2" = b."colb2"
WHERE a."cola1" = 'valuea2'
and ( b."colb2" is null or b."colb3" = 'valueb3' )
OP: I've got a mini-workaround which goes close (This may only work given this is an inner join.)
select a.* from table1 a
inner join table2 b on a."cola1" = b."COLb1"
WHERE
(a."cola2" = 'valuea1')
OR (a."cola2" = 'valuea2' and b."colb1" = 'valueb3')
Sometimes writing code out can prompt some alternative thinking. Self-Therapy sort of. Thanks for your input.