“Not exists” across multiple joins - postgresql

I am learning sql (postgres) and id like to find values that do not exist.
I have a table, table 1 with ids and i want to find those ids that are not in table 4.
I have to join between 3 tables as table 1 holds id and table 4 contact_id (not the same number)
The tables 2,3 need to be joined as that connects the ids.
So how do i do that with “not exists”?
Select t1.id, table4.contact_id
From table1 t1
Join table2 using(id)
Join table3 using(id)
Join table4 using(contact_id)
Where not exists (
Select 1
From table4
Where table4.contact_id=t1.id
);
It returns no values, but should
No error msg…
I have thinking error i assume

Your query probably returns no values because you join table4 on contact_id and then you exclude in the WHERE clause the rows which come from this join.
To find values that don't exist, you can usually use LEFT JOIN or RIGHT JOIN or FULL OUTER JOIN and then filter the rows with NULL values in the WHERE clause.
Try this :
SELECT t1.id
FROM table1 t1
LEFT JOIN table2 t2 using(id)
LEFT JOIN table3 t3 using(id)
LEFT JOIN table4 t4 using(contact_id)
WHERE t4.contact_id IS NULL

Related

How do I join two tables with same column names keeping values from one the tables

I have these two tables:
Table1
-------
id|a|b|c|d|
1 |0|1|0|6|
and
Table2
-------
id|a|c|
1 |3|2|
How do I join these two tables keeping the values from table2 but also the columns from table1, so that the table would look like this afterwards:
TableJoined
-------
id|a|b|c|d|
1 |3|1|2|6|
Tried with
SELECT * FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
hoping that the first table mentioned would be the overrider
Or I guess you could do:
SELECT b.id, a.a, b.b, a.c, b.d FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
You can achieve that by qualifying the * with the table alias:
SELECT a.* FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
But you should never use * in a SELECT list except in ad-hoc queries. (The exception is count(*) which is OK to use).

TSQL select all columns from join with same names

If I have a query
select * into #tmp1 from dbo.t1 inner join dbo.t2 on t1.Sender_Id=t2.Id
I get an error
Column names in each table must be unique. Column name 'Id' in table '#tmp1' is specified more than once.
How can I do the same thing without resorting to
select t1.Id as t1id, t1.col2. ... t1.col30, t2.Id as t2id, ... t2.col40 as t2col40 from ...
notation.
I just need to quickly and manualy examine several tables, so I'd like to have a quick way of examining joins.
If you have to persist the result via select * into #tmp or want to create a view, every field name has to be unique and you will have to uses aliases for fields with identical names.
A simple query does not need unique names.
Yes, columns name must unique in select statement, in your case, you have for example two (02) id, one from tbl1, and the other one from tbl2, on esolution is list them as:
Select t1.id, t2.id
From tbl1 as t1 Inner Join tbl2 as t2 on t1.id = t2.id
Hope this help.
Or, if you have columns with same name in both tables, use this:
Select t1.*, t2.* From tbl1 as t1 Inner join tbl2 as t2 On t1.id = t2.id
Regards

Postgresql how to select values in the column from one table that are only available in another table?

I am using Postgresql and need to query two tables like this:
Table1
ID Bill
A 1
B 2
B 3
C 4
Table2
ID
A
B
I want a table with all the columns in Table1 but keeping only the records with IDs that are available in Table2 (A and B in this case). Also, Table2's ID is unique.
ID Bill
A 1
B 2
B 3
Which join I should use or if I can use WHERE statement?
Thanks!
SELECT Table1.*
FROM Table1
INNER JOIN Table2 USING (ID);
or
SELECT *
FROM Table1
WHERE ID IN (SELECT ID FROM Table2);
but the first one is better for performance reason.
SELECT *
FROM Table1
WHERE EXISTS (
SELECT 1 FROM Table2 WHERE Table2.ID = Table1.ID LIMIT 1
)

How to use "as" to set alias for joined tables in oracle 10

I wrote this, and it is wrong syntax, help me fix it, I want 'T' to be an alias of the result of the two inner joins.
select T.id
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w as T;
You cannot use aliases to name the "entire" join, you can, however, put aliases on individual tables of the join:
select t1.id
from table1 t1
inner join table2 t2 on t1.x = t2.y
inner join table3 t3 on t3.z = t1.w
In the projection, you will have to use the alias of the table, which defines the id column you are going to select.
You can't directly name the result of a join. One option is to use a subquery:
select T.id
from (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
) T
Another option is subquery factoring:
with T as (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
)
select T.id
from T

How to write subquery in Criteria

I have a SQL like this:
Select tbl.id, tbl.name
From
(select table1.id, table1.name
from table1
inner join table2 on table1.id = table2.id
order by table2.priority
) tbl
group by table1.id
order by table1.name
What I'm trying to achieve is to first sort (order by table2.priority), and then get the record with table1.id, name with highest priority.
Note, MAX(table2.priority) doesn't work here, because table1 to table2 is one to many, and for one table1 record, table2 can have N records with the highest priority = 1, where another table1 record with highest priority = 3.
If you only need one record from the result, and they are in order such that the record you need is at the end (or beginning) of the sort, simply limit the results to one. i.e:
SELECT tbl.id, tbl.name
FROM (
SELECT table1.id, table1.name
FROM table1
INNER JOIN table2 ON table1.id = table2.id
ORDER BY table2.priority
) tbl
GROUP BY table1.id
ORDER BY table1.name
LIMIT 1;
Note that depending on the order, you could specify ASC or DESC to ensure the correct record is the one you retrieve.