I would like to use the SQL CASE keyword to evaluate the result of an inner query, in particular to check whether there is no record:
PseudoCode:
UPDATE tableA AS outerTable
SET field = CASE
WHEN (
SELECT *
FROM tableB
WHERE innerField = outerTable.field
) IS [doesn't have result]
THEN (
...
)
ELSE "default"
END
How can I code this condition? I've tried with IS NULL but it doesn't seem to work (
Scalar subquery produced more than one element)
You are looking for NOT EXISTS:
WHEN NOT EXISTS (SELECT *
FROM tableB b
WHERE b.innerField = outerTable.field
)
THEN . . .
Related
Below is some pseudocode that I need to retrieve data from a postgresql database. The subquery is where I am having trouble figuring out how to do correctly.
I need to include any record that has that has an output_type='TEXT' and if the output_type does not have 'TEXT' use a different criteria to ensure it is included.
Select * from tablename
left join table2 on table2.fk_id = tablename.pkid
where table2.letterid = 5
and table2.pkid not exist( select * from table3 where
if the table3.output = 'text'
include the record
else not table3.output = 'text'
if table3.sentdate is null
the record)
NOT EXISTS ( is how I do this generally. You can join with the other statement's tables in there, as I'm doing in this example with table2.pkid.
SELECT * FROM tablename
LEFT JOIN table2 ON (
table2.fk_id = tablename.pkid
AND table2.letterid = 5
AND NOT EXISTS (
SELECT * FROM table3
WHERE table3.pkid = table2.pkid
AND ... -- I don't quite follow what you're trying to do with the if/else, but it'd go here
)
);
table2.pkid NOT IN (SELECT table3.pkid ... also works for this. Not sure if it'll have the same performance or not, but personally I prefer the flexibility of NOT EXISTS anyway.
I have the following SQL query,
CASE
WHEN (SELECT COUNT(*)
FROM MyTable AS Parameter
INNER JOIN Table ON Parameter.Attribute1 = Table.Attribute2
WHERE FD.DefID= Parameter.DefID AND Parameter.VTypeID = 1) = 0
THEN (
SELECT * from Table2)
ELSE
NULL
END AS Items
Basically, I would like to ensure that conditional execution is only if the query result count is 0.
How should I modify it to use EXISTS/NOT EXISTS keyword?
You can use exists to do that like so:
SELECT * from Table2
WHERE NOT EXISTS(
SELECT 1
FROM MyTable AS Parameter
INNER JOIN Table ON Parameter.Attribute1 = Table.Attribute2
WHERE FD.DefID= Parameter.DefID AND Parameter.VTypeID = 1)
If column A is not empty I should add one condition and if it is empty, then I should add another condition. Something like this:
select *
from table t
where case when len(t.A) > 0 then t.A = (select B from anothertable )
else t.C = (select D from anothertable)
As this does not compiles, and I can't use IF clause within WHERE is there any other way to achieve this?
We can rephrase the login in the WHERE clause to make it work:
SELECT *
FROM table_t
WHERE
(LEN(t.A) > 0 AND t.A IN (SELECT B FROM anothertable) ) OR
(LEN(t.A) <= 0) AND t.C IN (SELECT D FROM anothertable) );
To address the comment by #HoneyBadger if the subqueries on anothertable return more than one record, then this query would error out if we used t.A = (subquery). If you intend to use equals, then you would have to ensure that the subquery only returns a single record. Your suggestion to use WHERE IN might fix the problem.
Need your help to know if possible to select values from a table with the below condition :
Table content : matching between 2 objects
(Id_obj_A; name_obj_A; country_obj_A; Id_obj_B; name_obj_B; country_obj_B)
Select *
from table
Where (only if country_obj_A <> country_obj_B)
Many thanks for your help
Yes. There are a few ways, one is to use NOT EXISTS like this:
select
*
from tableA
where NOT EXISTS (
select NULL
from tableB
where tableB.country_obj_B = tableA.country_obj_A
)
or, using NOT IN
select
*
from tableA
where country_obj_A NOT IN (
select country_obj_B
from tableB
)
or, using a LEFT JOIN then exclude the joined rows:
select
*
from tableA
left join tableB on tableA.country_obj_A = tableB.country_obj_B
where tableB.country_obj_B IS NULL
I am totally new to sql, I have a table like:
Using SQL, I want to select those rows that have no "INPROGRESS" state for the same LOCKID. For example, in above table query should return rows with id 4, 5, 6. Thanks.
You can use the NOT IN statement to exclude rows that have an 'INPROGRESS'. E.g.:
SELECT *
FROM tbl
WHERE LOCKID NOT IN ( SELECT LOCKID
FROM tbl
WHERE STATE = 'INPROGRESS' )
You can also use NOT EXISTS to do the same thing
SELECT *
FROM tbl t1
WHERE NOT EXISTS ( SELECT *
FROM tbl t2
WHERE t2.STATE = 'INPROGRESS'
AND t1.LOCKID = t2.LOCKID )
Sometimes one or the other construct will perform better, but in most cases, in my experience, they are pretty much equivalent.
Return all records from table (aliased "A") where state is is not inprogress provided that the lockID is not found in a set of data with a state of inprogress.
This uses a concept of a correlated query tying the inner query to outer. the select 1 in the subquery is throw away (but since the compiler requires a select to return a value even though we don't use it) since we only care about the LOCKID's matching.
SELECT *
FROM TABLE A
WHERE A.STATE <> 'INPROGRESS'
AND NOT EXISTS (SELECT 1
FROM TABLE B
WHERE B.STATE = 'INPROGRESS'
AND A.LOCKID = B.LOCKID)