SQL — Union two tables but Join on one of the columns - sql

I have two tables that look like this:
Table 1:
name | event | country
Table 2:
name | event
There are no overlapping rows between Table 1 and Table 2, because of the 'event' column. I wanted to union Table 1 with Table 2 since there are no overlaps, but I also want to fill in 'country' for Table 2 using the values from Table 1, with 'name' as the Join key. How do I do this?

If the relation of the 2 tables is 1:1 you can use UNION ALL for table1 and a query that joins (with a left join just in case there are no matches) table2 to table1 to retrieve the value of the column country:
select t1.* from table1 t1
union all
select t2.*, t1.country
from table2 t2 left join table1 t1
on t1.name = t2.name
or with a correlated subquery:
select t1.* from table1 t1
union all
select t2.*, (select t1.country from table1 t1 where t1.name = t2.name)
from table2 t2

Try this
SELECT * FROM TABLE1 t1
UNION
Select t2.*, t1.country from table2 t2
Join table1 t1 on t2.name=t1.name

This sounds like a full join:
select *
from table1 t1 full join
table2 t2
using (name, event);
If your database doesn't support full join, you can use:
select t1.name, t1.event, t1.country
from table1 t1
union all
select t2.name, t2.event, null
from table2 t2
where not exists (select 1 from table1 t1 where t1.name = t2.name and t1.event = t2.event);

Related

Union two tables with one different column

I have two almost identical tables except one column.
table1
id name amount
1 nm1 15
2 nm2 20
table1
id name amt
1 nm1 15
2 nm2 20
Now I have other joins but I want to avoid have it all twice but rather have more simple sql code.
At the moment I have to do all twice:
select t1.id, t1.name, t1.amount from table1 t1
left outer join.......
union all
select t2.id, t2.name, t2.amt as amount from table2 t2
left outer join.......
I would like to have something like:
select t1.id, t1.name, t1.amount from (select * from table1 union all select * from table2) t1
but this one column "amount" prevents it.
Is there a way how to handle it?
Do the union all before the join:
select t.id, t.name, t.amount, . . .
from (select t1.* from table1 t1 union all
select t2.* from table2 t2
) t left outer join.......

Applying joins conditionally in SQL Server

I have some set of records, but now i have to select only those records from this set which have theeir Id in either of the two tables.
Suppose I have table1 which contains
Id Name
----------
1 Name1
2 Name2
Now I need to select only those records from table one
which have either their id in table2 or in table3
I was trying to apply or operator witin inner join like:
select *
from table1
inner join table2 on table2.id = table1.id or
inner join table3 on table3.id = table1.id.
Is it possible? What is the best method to approach this? Actually I am also not able to use
if exist(select 1 from table2 where id=table1.id) then select from table1
Could someone help me to get over this?
Use left join and then check if at least one of the joins has found a relation
select t1.*
from table1 t1
left join table2 t2 on t2.id = t1.id
left join table3 t3 on t3.id = t1.id
where t2.id is not null
or t3.is is not null
I would be inclined to use exists:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 where t2.id = t1.id) or
exists (select 1 from table3 t3 where t3.id = t1.id) ;
The advantage to using exists (or in) over a join involves duplicate rows. If table2 or table3 have multiple rows for a given id, then a version using join will produce multiple rows in the result set.
I think the most efficient way is to use UNION on table2 and table3 and join to it :
SELECT t1.*
FROM table1 t1
INNER JOIN(SELECT id FROM Table2
UNION
SELECT id FROM Table3) s
ON(t.id = s.id)
Alternatively, you can use below SQL as well:
SELECT *
FROM dbo.Table1
WHERE id Table1.IN ( SELECT table2.id
FROM dbo.table2 )
OR Table1.id IN ( SELECT table3.id
FROM Table3 )

Compare 2 Tables and return full data

Im struggling with writing a query and infact do not know which query is relevant for the task (Union, Inner/Outer Join etc)
I have a table of data that is revised each week and I need to report on the differences.
i.e if it gets deleted in table 1, table 2 or a field changes.
I have included an image to show the data from the revised table and also what I would like as an output to report on (Ignore the Comments, they are only for reference)
Any help would be appreciated.
I don't believe access supports full outer joins ...
so... we use a left join and a right join and a union along with a case statement.
Select A.*, case when T1.Name=T2.Name and T1.Area=T2.Area then 'In T1 and T2 and Equal'
when T2.Name is null then 'In T1 Only'
when T1.Name is null then 'in T2 Only,omitted in T1'
when T1.Name = T2.Name and T1.Area<> T2.Area then 'In T1 and T2 Different area' from (
Select t1.*, T2.*
FROM table1 T1
LEFT JOIn table2 T2
on T1.Name = T2.Name and T1.Area = T2.Area
UNION
Select t1.*, T2.*
FROM table1 T1
RIGHT JOIN table2 T2
on T1.Name = T2.Name and T1.Area = T2.Area) A
FULL OUTER JOIN to find any rows from table 1 or table 2 and align them whenever possible then you can use a CASE to create the comment column based on the comparison of AREA, or NAME being null.
But MS ACCESS doesn't have FULL JOIN so we need LEFT JOIN UNION RIGHT JOIN.
Also CASE statement is VB syntax, use switch
SELECT
t1.*,
t2.*,
switch(
t2.name IS NULL,'IN TABLE 1 ONLY',
t1.area <> t2.area,'IN TABLE 1 AND 2 SAME NAME BUT AREA DIFFERENT IN TABLE 2',
true,'IN TABLE 1 AND 2 AND EQUAL')
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.name = t2.name
UNION
SELECT
t1.*,
t2.*,
switch(
t1.name IS NULL,'IN TABLE 2 ONLY, OMITTED IN TABLE 1',
t1.area <> t2.area,'IN TABLE 1 AND 2 SAME NAME BUT AREA DIFFERENT IN TABLE 2',
true,'IN TABLE 1 AND 2 AND EQUAL')
FROM table1 AS t1
RIGHT JOIN table2 AS t2
ON t1.name = t2.name

How to select same value(string) from two tables

Table_1 Table_2
name=john name=john
age=15 age=18
My goal is to select john, because it is the same name.
Now my idea is:
SELECT * FROM Table_1,Table_2 WHERE (name=name).
You can use an inner join to merge the two tables where the key you specified are same like:
Select t1.name, t1.age as AgeFromT1, t2.age as AgeFromT2
from Table_1 t1
inner join Table_2 t2 on t1.name = t2.name
Or you can use a subquery like:
Select table_1.*
from table_1
where name in (
Select Table_2.name
from Table_2
)

How to use outside column in subquery

I have following query-
select * from
Table1 t1 , table2 t2 ,
(select idCol from table3) t3
My question is - Can I use table t2 inside subquery?
like this
select * from
Table1 t1 , table2 t2 ,
(select idCol, t2.nameCol from table3) t3
Obviously this gives error invalid identifier t2.nameCol
But if I write as follows, it give unnecessaru extra rows
select * from
Table1 t1 , table2 t2 ,
(select idCol, t2.nameCol from table3, table2 t2) t3
any other way to do this?
EDIT
Basically what I am trying to achieve is following
select * from
Table1 t1 , table2 t2 ,
(select
case
when t2.nameCol = 'ABC' then 'ABC'
else idCol
end idCol from table3) t3
To join a table only when certain criteria is met is called an outer join. Here is how:
select *
from table1 t1
inner join table2 t2 on <join criteria here>
left outer join table3 t3 on t2.namecol <> 'ABC' and <join criteria here>;
It may suffice in your case, however, to move the subquery to your SELECT clause:
select
t1.*,
t2.*,
case when t2.namecol = 'ABC' then
'ABC'
else
(select idcol from table3 t3 where <join criteria here>)
end
from table1 t1
inner join table2 t2 on <join criteria here>;
You can try below. I am sure you have some kind of join between t1 and t2. IN such case, you can add same at the end of the statement.
SELECT t1.*,
t2.*,
( SELECT CASE
WHERE t2.nameco1 = 'ABC' THEN 'ABC'
ELSE idcol
END idcol
FROM table3) idcol
FROM table1 t1,
table2 t2