Joining tables in Postgres - sql

I have a table...
col1 | id | col3|
---------------------
1 |123 | |
2 |456 | |
3 |789 | |
And I have another table...
id | name |
------------
123 | Tom |
456 | Kate |
789 | Pork |
101 |Winter|
102 |Roll |
I want to join the tables together to get a result that looks like this...
col1 | id | col3| name
----------------------------
1 |123 | | Tom
2 |456 | | Kate
3 |789 | | Pork
Can someone help me please?
Thanks in advance

If you only want the data where id from one table matches to id at another table then you can do an inner join like this:
SELECT *
FROM table1
INNER JOIN table2 ON table2.id = table1.id
If you want all the data from the first table but only matched id data from the second table then you can do this:
SELECT *
FROM table1
LEFT JOIN JOIN table2 ON table2.id = table1.id
For more information about Joins you an refer to this link - SQL joins

use inner join between two tables
select col1,table1.id,col3,name from table1
inner join table2 on table1.id =table2.id

Do the JOIN :
SELECT t1.*, t2.name
FROM table1 t1 INNER JOIN
table2 t2
ON t1.id = t2.id;

Related

Joining Two Tables, Same ID - Return both IDs even if Null

I have two tables
+-----+----------+
| SKU | Quantity |
+-----+----------+
| ABC | 30 |
| DEF | 40 |
+-----+----------+
+-----+----------+
| SKU | OnOrder |
+-----+----------+
| ABC | 90 |
| XYZ | 80 |
+-----+----------+
I want to join both tables on SKU when there is a match, but also return SKU from both tables when there isn't a match. So the results would be:
+-----+---------+---------+
| SKU | OnOrder | OnOrder |
+-----+---------+---------+
| ABC | 90 | 30 |
| DEF | 40 | |
| XYZ | | 80 |
+-----+---------+---------+
I'm thinking this would be accomplished by using a left join and a right join and by doing a union but I can't seem to get the code right.
Your help is much appreciated!
You can use a full join:
select coalesce(t1.sku, t2.sku), t1.quantity, t2.onorder
from table1 t1 full join
table2 t2
on t1.sku = t2.sku;
If your database doesn't support full join, the best workaround is probably:
select t1.sku, t1.quantity, t2.onorder
from table1 t1 left join
table2 t2
on t1.sku = t2.sku
union all
select t2.sku, null, t2.onorder
from table2
where not exists (select 1 from table1 t1 where t1.sku = t2.sku);
You can first select all the SKU values and then join that to both tables:
with skus(sku) as (
select sku from table1
union
select sku from table2
)
select a.sku, b.quantity, c.onorder
from skus a
left join table1 b on a.sku = b.sku
left join table2 c on a.sku = c.sku;

Join same table with different column

Hi This may be a stupid question but I have a scenario where my columns tl1,tl2 and tl3 refers to column id table structure is below,
id | name | email | tl1 | tl1 | tl3 |
1 | xyz |x#g.com| null| 1 | 2 |
======================================
2 | abc |z#g.com| null| 1 | 3 |
======================================
3 | def |d#g.com| 1 | 2 | 4 |
SO need to write a query to get the name of tl1,tl2 and tl3,
like below
id | name | email | tl1 | tl1 | tl3 |
1 | xyz |x#g.com| null| xyz | abc |
======================================
2 | abc |z#g.com| null| xyz | def|
======================================
3 | def |d#g.com| xyz | abc | ghi |
I am not able to create query for this scenario, I actually created one but not getting unique records
This is the query which I tried
select distinct a.branch_code,a.email,a.partner_name,a.role_assigned,a.category,b.partner_name as tl1,
c.partner_name as tl2,d.partner_name as tl3
from branch_master as a
left join branch_master as b on b.tl1 = a.branch_code
left join branch_master as c on c.tl2 = a.branch_code
left join branch_master as d on d.tl3 = a.branch_code
Any help would be appreciated.
You need to left join the table 3 times with itself:
select
t.id, t.name, t.email,
t1.name name1, t2.name name2, t3.name name3
from tablename t
left join tablename t1 on t1.id = t.tl1
left join tablename t2 on t2.id = t.tl2
left join tablename t2 on t3.id = t.tl3
First, this is generally a bad data format -- typically, you want the values in different tables. There are some cases where it might make sense to have the data across columns -- for instance, if role are different: submitted_by, processed_by, approved_by. But generally, you want a junction/association table.
The solution to your problem, though, is multiple left joins:
select t.*, t1.email as email1, t2.email as email2, t2.email as email3
from t left join
t t1
on t1.tl1 = t.id left join
t t2
on t2.tl2 = t.id left join
t t3
on t3.tl3 = t.id;

How to insert into one column from two table's two different column?

I got three tables.
I want to insert below value to table3.stat with "one" sql statement.
1.select status from table0, table2 where table0.serial=table2.num
2.select condition from table1, table2 where table1.ID=table2.num
Is it possible with postgresql?
table0:
| serial | status | |
|--------|--------|---|
| a22 | good | |
| a33 | bad | |
| a11 | bad | |
table1:
| ID | condition | |
|-----|-----------|---|
| a00 | awesome | |
| a44 | bad | |
| a11 | bad | |
table2:
| num | | |
|------|---|---|
| a00 | | |
| a44 | | |
| a22 | | |
| a33 | | |
table3:
| num | stat |
|-----|------|
| | |
| - | - |
desired result:
| num | stat |
|-----|-------|
| a22 | good |
| a33 | bad |
| a00 |awesome|
| a44 | bad |
SQL DEMO
Use UNION ALL even when are two select, is just one statement
INSERT INTO table3 ("num", "stat")
select table2."num", table0."status"
from table0
JOIN table2 ON table0."serial"=table2."num"
UNION ALL
select table2."num", table1."condition"
from table1
JOIN table2 ON table1."ID"=table2."num"
;
seems you are looking for a query as
select table2.num, table0.status
from table0
INNER JOIN table2 ON table0.serial=table2.num
INNER JOIN table1 ON table1.ID=table2.num
insert into table3 (num, stat)
select table2.num, table0.status
from table0
INNER JOIN table2 ON table0.serial=table2.num
INNER JOIN table1 ON table1.ID=table2.num
or if the column don't always match you could use left join (as suggested by Juan Carlos Oropeza)
select table2.num, table0.status
from table0
LEFT JOIN table2 ON table0.serial=table2.num
LEFT JOIN table1 ON table1.ID=table2.num
insert into table3 (num, stat)
select table2.num, table0.status
from table0
LEFT JOIN table2 ON table0.serial=table2.num
LEFT JOIN table1 ON table1.ID=table2.num
Update
related to your comment
For the inner join you have not valid value in table1 .. so this return no result .. for left join .. the the left join return values also when there is not match then you have also null value .. the unique condition that work
based on you fiddle
could be
select table2."num", table0."status"
from table0
INNER JOIN table2 ON table0."serial"=table2."num"
LEFT JOIN table1 ON table1."ID"=table2."num";
http://sqlfiddle.com/#!17/46bf1/22

SQL query to get all the rows from multiple tables even it has uneven primary and foreign keys

I have multiple tables, like below
Table-1:
ID | Name
----------------
1 | John
2 | Doe
3 | Mark
4 | Hill
5 | Ram
Table-2:
ID | place
----------------
1 | CA
2 | NY
4 | AK
5 | CT
Table-3:
ID | age
----------------
2 | 35
3 | 23
4 | 54
I need to get the output table as
Table-1:
ID | Name | Place | Age
-----------------------------------
1 | John | CA |
2 | Doe | NY | 35
3 | Mark | | 23
4 | Hill | AK | 54
5 | Ram | CT |
I tried using join and union, however I could not find the solution. Could you please someone give me the solutions?
You need to use join as below:
select t1.id, t1.name,t2.place, t3.age
from table1 t1 join table2 t2 on t1.id = t2.id
left join table3 t3 on t1.id = t3.id
The result as shown can be obtained using an outer join:
select *
from table1
left join table2 using (id)
left join table3 using (id);
The join through the using operator has the nice side effect that the ID column will only show up once in the result even though I have used select *
Your example doesn't show this, but if you have IDs in table2 that are not in table1 but you still want them in the result, you need to use a full outer join.
select *
from table1
full join table2 using (id)
full join table3 using (id);
The using (id) know has another nice side effect: it will automatically use the ID value from whichever table the id came from without the need to use a coalesce(id) in the select list.
select t1.id, name, place, age
from table1 t1
` left outer join table2 on t1.id=t2.id
left outer join table3 on t1.id=t3.id;

SQL Query to Bring Back where Row Count is Greater than 1

I have two tables.They have the same data but from different sources. I would like to find all columns from both tables that where id in table 2 occurs more than once in table 1. Another way to look at it is if table2.id occurs only once in table1.id dont bring it back.
I have been thinking it would be some combination of group by and order by clause that can get this done but its not getting the right results. How would you express this in a SQL query?
Table1
| id | info | state | date |
| 1 | 123 | TX | 12-DEC-09 |
| 1 | 123 | NM | 12-DEC-09 |
| 2 | 789 | NY | 14-DEC-09 |
Table2
| id | info | state | date |
| 1 | 789 | TX | 14-DEC-09 |
| 2 | 789 | NY | 14-DEC-09 |
Output
|table2.id| table2.info | table2.state| table2.date|table1.id|table1.info|table1.state|table1.date|
| 1 | 789 | TX | 14-DEC-09 | 1 | 123 | TX | 12-DEC-09 |
| 1 | 789 | TX | 14-DEC-09 || 1 | 123 | NM | 12-DEC-09 |
If you using MSSQL try using a Common Table Expression
WITH cte AS (SELECT T1.ID, COUNT(*) as Num FROM Table1 T1
INNER JOIN Table2 T2 ON T1.ID = T2.ID
GROUP BY T1.ID
HAVING COUNT(*) > 1)
SELECT * FROM cte
INNER JOIN Table1 T1 ON cte.ID = T1.ID
INNER JOIN Table2 T2 ON cte.ID = T2.ID
First, I would suggest adding an auto-incrementing column to your tables to make queries like this much easier to write (you still keep your ID as you have it now for relational-mapping). For example:
Table 1:
TableID int
ID int
Info int
State varchar
Date date
Table 2:
TableID int
ID int
Info int
State varchar
Date date
Then your query would be really easy, no need to group, use CTEs, or row_over partitioning:
SELECT *
FROM Table2 T2
JOIN Table1 T1
ON T2.ID = T1.ID
JOIN Table1 T1Duplicate
ON T2.ID = ID
AND T1.TableID <> T1Duplicate.TableID
It's a lot easier to read. Furthermore, there are lots of scenarios where an auto-incrementing ID field is benefitial.
I find this a much simpler way to do it:
select TableA.*,TableB.*
from TableA
inner join TableB
on TableA.id=TableB.id
where TableA.id in
(select distinct id
from TableA
group by id
having count(*) > 1)