sql subquery from where in - sql

I'm writing something along these lines:
select fielda,fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb
where fieldid = list_of_ids[i])
from tablea
where fieldid in (list_of_ids);
In the subquery I'd like to use the value from the outer where clause. So if list_of_ids is 123,456,789 the fieldid in the subquery will be 123, the second 456, etc. Is this possible?

You just need to use ta.fieldid instead of list_of_ids[i]
select ta.fielda,ta.fieldb,
(select sum(tb.field1)-sum(tb.field2) as fieldc
from tableb tb
where tb.fieldid = ta.fieldid )
from tablea ta
where ta.fieldid in (list_of_ids);

A subquery is anchored to the individual record in the outer query.
select fielda,fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb
where tableb.fieldid = tablea.fieldid)
from tablea
where tablea.fieldid in (list_of_ids);
By just using a simple comparison operator to correlate your subquery with your outer query, your subquery will compare against any fieldids found by the outer query as well.

try this code :
select ta.fielda,ta.fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb tb
where tb.fieldid = ta.fieldid )
from tablea ta
where ta.fieldid in (list_of_ids);

Related

How to create a select clause using a subquery

I have the following sql statement:
WITH
subquery AS (
select distinct id from a_table where some_field in (1,2,)
)
select id from another_table where id in subquery;
Edit
JOIN is not an option (this is just a reduced example of a bigger query)
But that obviously does not work. The id field exists in both tables (with a different name, but values are the same: numeric ids). Basically what I want to do is filter by the result of the subquery, like a kind of intersection.
Any idea how to write that query in a correct way?
You need a subquery for the second operand of IN that SELECTs from the CTE.
... IN (SELECT id FROM subquery) ...
But I would recommend to rewrite it as a JOIN.
Are you able to join on ID and then filter on the Where clause?
select a.id
from a.table
inner join b.table on a.id = b.id
where b.column in (1,2)
Since you only want the id from another_table you can use exists
with s as (
select id
from a_table
where some_field in (1,2)
)
select id
from another_table t
where exists ( select * from s where s.id=t.id )
But the CTE is really redundant since all you are doing is
select id
from another_table t
where exists (
select * from a_table a where a.id=t.id and a.some_field in (1,2)
)

How to limit records considered in a nested select within a join?

Curious to see if there is a way to write the following T-SQL statement (this one errors with cannot bind TableA in the nested select.) Removing the error line seems to consider all records from TableB then performs the join.
select *
from TableA A
join (
select TableAid, TableBinfo
from TableB
where TableB.TableAid = A.TableAid -- error line
group by TableAid, TableBinfo
) B on
A.TableAid = B.TableAid
where A.TableAid = 123
Is the following SQL the best I can hope for?
I'd really like to limit the distinct comparison to just the one column in the one table rather than all the columns I select. I don't control the database and it doesn't have indexes on anything but primary keys.
select A.TableAid, B.TableBinfo
from TableA A
join TableB B on
A.TableAid = B.TableAid
where A.TableAid = 123
group by A.TableAid, B.TableBinfo
Your first example looks like you're trying to do an APPLY over a correlated subquery:
SELECT *
FROM TableA a
CROSS APPLY
(
SELECT t.TableBInfo
FROM TableB t
WHERE a.TableAId = b.TableBId
GROUP BY b.TableBInfo
) b
WHERE a.TableAId = 123

SQL Query to compare columns in different table

I have TableA and TableB which contains identical columns but they have different records.
How do I find out which "UniqueID" is not in TableA but in TableB?
I have been doing
select tc.uniqueid, td.uniqueid
from tab1c as tc
left join tab2c as td
where tc.uniqueid != td.uniqueid;
but it doesnt seem to be correct.
Use left join:
select tc.uniqueid, td.uniqueid
from tab1c as tc
left join tab2c as td
on tc.uniqueid = td.uniqueid
where td.uniqueid = NULL; --Will get all uid in tab1c and not in tab2c
The same efficient and more readability way is NOT EXISTS:
select tc.uniqueid
from tab1c as tc
WHERE NOT EXISTS (SELECT * FROM tab2c as td
WHERE tc.uniqueid = td.uniqueid)
The below query will find all the unique id`s which is not there in tableA
SELECT UNIQUEID FROM TABLEB WHERE UNIQUEID NOT IN (SELECT DISTINCT UNIQUEID FROM TABLEA);
Maybe not the most efficient way but you can use EXCEPT
SELECT UNIQUEID
FROM tab1c
EXCEPT
SELECT UNIQUEID
FROM tab2c

Using subqueries in PostgreSQL

I'm only about a day into using PostgreSQL and have what is pry a quite simple question. I want to create a left outer join to search for mismatch values. I'd like from the join create a subquery which selects the null values and then updates are based on this selection. What I have for the left outer join looks like this:
SELECT TableA.field1, TableA.field2, TableB.field3
FROM
TableA
LEFT OUTER JOIN TableB ON TableA.field1 = TableB.field1
This works for the join. However, I can't manage to figure out how to then use a subquery to return only rows where TableB.field1 is null.
You don't need a subquery:
SELECT TableA.field1, TableA.field2, TableB.field1
FROM TableA
LEFT OUTER JOIN TableB ON TableA.field1 = TableB.field1
where tableB.field1 IS NULL;
Not sure what you mean with "and then updates a based on this selection" though
Here is how you ...
Select rows which are not present in other table
I suppose you want to update rows based on this selection. Use the FROM clause to join more (derived) tables in an UPDATE:
UPDATE some_table t
SET (field1, field2, field3)
= (a.field1, a.field2, a.field3)
FROM (
SELECT a.a_id, a.field1, a.field2, a.field3
FROM tablea a
LEFT JOIN tableb b USING (field1)
WHERE b.field1 IS NULL
) a
WHERE t.a_id = a.a_id; -- join on the connecting column
Using the short syntax variant to update multiple columns.

Having trouble with this simple SQL Select statement

I have two tables, A and B.
Both have the exact same columns.
I need to select all the items in TableA that ARE NOT in TableB.
This is intersection, right? How can I do this?
assuming TableA and TableB have a primary key of name id.
select TableA.*
from TableA
left outer join TableB on TableB.id = TableA.id
where TableB.id is null;
This will find all entries where table b does not have an instance of table a's id.
You could use the EXISTS clause
SELECT * FROM TableA
WHERE NOT Exists
(
SELECT Column1 FROM TableB
WHERE TableA.Column1 = Table2.Column1
AND TableA.Column2 = Table2.Column2
....
)
Replace .... with the rest of the columns in the two tables.
SELECT ColumnA, ColumnB
FROM TableA
EXCEPT
SELECT ColumnA, ColumnB
FROM TableB
You have your terminology wrong. The intersection would be the rows that are in both Table A and Table B. What you are actually looking for is the relative complement of A and B. To get a relative complement you want to do an antijoin:
SELECT * FROM TableA EXCEPT SELECT * FROM TableB.
or NOT IN
SELECT *
FROM TableA
WHERE TableA.Id NOT IN (SELECT TableB.Id FROM TableB)