SQL "Where exists" with multiple tables with aliases - sql

Example query:
Select id, id_dtm
From tableA
Where exists (
Select 1
From tableB b, tableC c, tableD d
Where b.id = id
And b.id_dtm = id_dtm
And b.id = c.id
And c.id = d.id);
The problem with the above query is that all 4 tables have columns named id and id_dtm.
When i run it, i get an error saying that the columns ORA-00918: column ambiguously defined
I could have fixed by using an alias in tableA but the problem is that the query is generated dynamically. The where exists portion is generated somewhere else and the bit before it is merged later so i cant use an alias as it is now.
Is there any way i can use id and id_dtm from tableA inside the where exists clause without using an alias for tableA?
Database is Oracle10G

Write the table name tableA:
Select id, id_dtm
From tableA
Where exists (
Select 1
From tableB b, tableC, tableD
Where tableB.id = tableA.id
And tableB.id_dtm = tableA.id_dtm
And tableB.id = tableC.id
And tableC.id = tableD.id)

I don't know your exact setup but why can't you set an alias on the outer table? It doesn't have to reflect the actual table used, just alias it with "outer" or something. The use that in the inner query, you already know that id exists in whatever table is used outside so outer.id would work fine.

The fields in the subquery which refer to tableA (i.e. id and id_dtm) also exist in the other tables, and so they are ambiguous. Solve this by prefixing those with the alias given to tableA:
Select A.id, A.id_dtm
From tableA A
Where exists (
Select 1
From tableB b, tableC c, tableD d
Where b.id = A.id
And b.id_dtm = A.id_dtm
And b.id = c.id
And c.id = d.id);

Related

SQL Get rows that doesn't appear in another table

I have this SQL problem: I have tables A and B. Table A has columns id and name, Table B amount and id which is a foreign key to table A.id.
I need to return all table A rows that don't have their id stored in table B. Any ideas?
So the complete opposite is:
SELECT *
FROM a
LEFT OUTER JOIN b ON a.id = b.id;
Here row what I need is left out of result
Just add a where clause:
SELECT a.*
FROM a LEFT OUTER JOIN
b
ON a.id = b.id
WHERE b.id IS NULL;
You can also use NOT EXISTS:
select a.*
from a
where not exists (select 1 from b where b.id = a.id);
In most databases, the two methods typically have similar performance.

Select Name instead OF ID in table with ID-Ref Column SQL

Lets say we have 2 Tables:
Table A Table B
- A_ID - B_ID
- A_Name - A_ID
I need a select statement, that selects * from Table B showing the A_NAME instead of the A_ID.
By trying it I got the following select statement which ... doesn't work to well. It is giving me a lot of nulls, but no names.
SELECT B_ID,
(select A_NAME from TableA as A where A.A_ID = B.A_ID) as Name
FROM TableB as B
Thanks for all your Answers.
The final solution:
The shown query DOES work (even though it may be slow) and the solutions in the answers also do work.
The problem why it didn't give results for me was because of my data. On another database with the same schema all the commands work.
You should try LEFT JOIN
SELECT
B_ID, A_Name
FROM
tableB B LEFT JOIN tableA A
ON B.A_ID = A.A_ID
you can do it with a join:
SELECT B.B_ID, A.A_Name
FROM B
INNER JOIN A
ON A.A_ID = B.A_ID;
Edit:
If you want only the entries from table b you can to it with a left join, like #jarlh said:
SELECT B.B_ID, A.A_Name
FROM B
LEFT JOIN A
ON A.A_ID = B.A_ID;

Can this be done with a single SQL Join?

I am not sure if this can be done with a single JOIN, but I basically have two tables with an ID column in common. To make it simple I'll say Table A just contains an ID while Table B contains an ID and Code. There is a 1:M relationship between Table A and Table B, however it's also possible an ID from Table A is not contained in Table B at all. I was hoping to have a query return every ID that exists in Table B within a particular code range, or does not exist in Table B at all.
I tried using a LEFT JOIN with something like:
SELECT A.id FROM A LEFT JOIN B ON A.id = B.id AND b.code BETWEEN '000' AND '123'
But, this still gives me the IDs that exist in Table B outside of the code range.
Use a left join, and filter the result to contain the codes in the range, and also the lines where there is no matching record in table B:
select
A.id
from
A
left join B on B.id = A.id
where
B.code between '000' and '123' or B.id is null
What about
SELECT id FROM A LEFT JOIN B ON A.id = B.id
WHERE b.code IS NULL OR b.code BETWEEN ' ' AND '123'

SQL select statement ORDER BY relationship to a second table?

I have table A, which contains a row for an int representing the table B object they relate to.
Multiple As can reference the same B. B does not reference A
I want to return As ordered by a row in the B object they relate to.
Is there a way to do this in one SQL statement? Or even 2?
Thank you.
You can put anything in your SELECT list and ORDER BY any column you'd like as long as it's in tablea or tableb
SELECT a.ID
FROM tablea
INNER JOIN tableb ON tablea.ID = tableb.ID
ORDER BY tableb.ID
Have you tried using
Select (columns that you want to display)
from TableA INNER JOIN TableB
ON TableA.col = TableB.col
Order By TableB.ColumnName

Retrive Records Form One Table as long as they do not exist in Another table T-SQL [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?
I need to wite a query that will retrieve the records from Table A , provided that the key in Table A does not exist in Table B.
Any help will be appreciated.
Thanks
select a.*
from
tableA a
left join tableB b
ON a.id = b.id
where
b.id is null
SELECT *
FROM A
WHERE ID NOT IN
(SELECT ID FROM B)
None of the above solutions would work if the key comprises of multiple columns.
If the tables have compound primary keys, you'll have to use a "NOT EXISTS" clause similar to the one below.
SELECT *
FROM TableA AS a
WHERE NOT EXISTS (
SELECT *
FROM TableB b
WHERE b.id1 = a.id1
AND b.id2 = a.id2
AND b.id3 = a.id3
);
Use a left join. The DB tries to map datasets from TableB to TableA using the id fields. If there is no fitting data set available in TableB, the TableB data gets NULL. Now you just have to check for TableB.id to be NULL.
SELECT TableA.* FROM TableA LEFT JOIN TableB ON TableA.id = TableB.id WHERE TableB.id IS NULL
Assuming:
TableA's Id = Id
TableB's Id = Id
select * from TableA ta where ta.Id not in (select Id from TableB)
SELECT * FROM TableA
WHERE NOT Exists(SELECT * FROM TableB WHERE id=TableA.id)
also works and it's almost self documenting...