Combine two tables on same columns - sql

I have 2 tables as showen below:
TABLE 1: Name Age Weight(Kilo)
Tom 16 56
Alex 29 89
TABLE 2: Name Age Sex
Tom 16 M
Alex 29 M
What I want to get:
TABLE 3: Name Age Sex Weight(Kilo)
Tom 16 M 56
Alex 29 M 89
I have tried Union/Union All and it doesn't work. Also tried to use Join but it gives me a table with duplicate values. Any idea how to do this?

Assuming your Name/Age values match up exactly between the two tables, a JOIN would be exactly what you're looking for.
select t1.Name, t1.Age, t2.Sex, t1.Weight
from Table1 t1
join Table2 t2 on t1.Name = t2.Name and t1.Age = t2.Age
If there is any possibility that there is no match between the tables, start with the one with the larger number of records, then do a left outer join:
For example, assume Table1 has every person, but Table2 may be missing some:
select t1.Name, t1.Age, t2.Sex, t1.Weight
from Table1 t1
left join Table2 t2 on t1.Name = t2.Name and t1.Age = t2.Age
If you might have records in either table that aren't in the other, a full outer join would work:
select
coalesce(t1.Name, t2.Name) [Name]
,coalesce(t1.Age, t2.Age) [Age]
,t2.Sex
,t1.Weight
from Table1 t1
full join Table2 t2 on t1.Name = t2.Name and t1.Age = t2.Age

Since it doesn't look like you have a PRIMARY KEY
SELECT
t1.*,
t2.Sex
FROM
table1 t1
INNER JOIN
tabel2 t2 on t1.Name = t2.Name and t1.Age = t2.Age
This is most likely still going to cause some duplicates in larger datasets, but I'm assuming you are looking for logic and posted some dummy data.

JOIN is exactly what you need, but you need to join on a unique identifier. In this case, the Name column is unique for those two records, but usually JOINs are done on generated IDs such as CustomerID or ClientID. Like others have posted, you can use the other columns in conjunction with the Name column to ensure you don't get duplicates by adding those columns in the ON section of the JOIN clause.
SELECT t1.Name, t1.Age, t2.Sex, t1.Weight
FROM Table1 t1
INNER JOIN Table2 t2
ON (t1.Name = t2.Name)
I suggest adding a unique identifier as a primary key so JOINs are a lot easier to do in the future.

SELECT t1.*,t2.Sex
FROM table1 t1 LEFT JOIN table2 t2 ON t1.Name=t2.Name

Related

sql join with like operator

Hi I have 2 tables in my sqltable in which my first table has id's like 111,112,113 etc. and second table has same column also have column id which contains values like 111|aa,112|ab,114|ad and i need to select all the ids from second table which contain part of id of first column like 2nd table contains 111 and 112 which also there in table1 as 111 and 112 how can i select those recods itried below query but didbt get result.
select t1.id,t2.id from table1 t1 left outer join table2 t2 where t2.id like t2.id +'%'
also tried.
select t1.id,t2.id from table1 t1 left outer join table2 t2 on t2.id like t2.id +'%'
can someone please give me a hint how should i do this.
You have to use CONCAT to add the % character:
SELECT t1.id,t2.id
FROM table1 t1 LEFT JOIN table2 t2 ON t2.id LIKE CONCAT(t1.id, '|%')
demo on dbfiddle.uk
Note: Also make sure you are using the correct columns on the ON clause. In the above demo and query t1.id is the numeric column (contains 111, 112 or 113) and t2.id is the string column (contains 111|aa, 112|ab or 114|ad).
To avoid unexpected behaviour on numbers greater than 999 you can add the pipe character | to the condition too.
You could try usingb a proper ON clause
select t1.id,t2.id
from table1 t1
left outer join table2 t2 ON t1.id like concat(t2.id, '%')
or
select t1.id,t2.id
from table1 t1
left outer join table2 t2 ON t2.id like concat(t1.id, '%')
for the join you should use the column from two table not from the same table

Comparing Two SQL Tables Based On Matching Column

I have two tables, T1 and T2. T1 looks like this:
ID Type Date
_____________________________
1 CA 11-17-2018
2 BA 7-12-2018
3 CA 4-1-2018
4 BA 1-17-2018
5 CA 9-30-2018
And T2 looks like this:
ID Type Date
_____________________________
1 CA 11-17-2018
2 BA 3-1-2018
3 CA 4-1-2018
4 CA 1-17-2018
5 CA 10-3-2018
I need a way to compare rows from the two tables that have matching IDs and see if the other values match or if they're different. I only want the output table to contain those IDs with differing values, and display those values. Thanks in advance.
Try this:
SELECT T1.ID, T1.Type as T1Type, T2.Type as T2Type, T1.Date as T1Date, T2.Date as T2Date
FROM T1
INNER JOIN T2
ON T1.ID = T2.ID
WHERE T1.DATE <> T2.DATE
OR T1.Type <> T2.Type
Notice that this query will only return result where the ID is present in both tables.
I think you need below something, inner join and comparison
select T1.*,T2.* from T1 inner join T2 on T1.id=T2.id
where T1.Type!=T2.Type and T1.Date!=T2.Date
You would use join:
select t1.*, t2.*
from t1 join
t2
on t1.id = t2.id
where (t1.type <> t2.type) or (t1.date <> t2.date)
you can put one foreign key in one of this tables, who will make reference to the other.
When you make a select, you can do a join of one table with other by the primary key and the foreign key.
SELECT column FROM table1 JOIN table2 ON table1.id_pk = table2.id_fk WHERE condition;
in WHERE you put something like
WHERE (table1.id != table2.id) OR (table1.type != table2.type) OR (table1.date != table2.date);

Search for if column has 'a' AND 'b'

Suppose you have two tables... table 1 and table 2.
table 1 columns are name / age / area
table 2 has area / job title
I would like to select area and job title only if the area includes both names 'sarah' and 'Phillip' (has to include BOTH the given names)
One way to do it is a combination of exists, group by having and count:
SELECT area, JobTitle
FROM Table2 t2
WHERE EXISTS
(
SELECT t1.Area
FROM Table1 t1
WHERE t1.Area = t2.Area
AND Name IN('sarah', 'Phillip')
GROUP BY t1.Area
HAVING COUNT(DISTINCT t1.Name) = 2
)
Another method is not quite as flexible as the aggregation method. However, you have two tables, and it might have better performance:
select t2.*
from table2 t2
where exists (select 1 from table1 t1 where t1.area = t2.area and t1.name = 'sarah') and
exists (select 1 from table1 t1 where t1.area = t2.area and t1.name = 'Phillip');
In particular, this can take advantage of an index on table1(area, name).
if you have a unique constraint on table1 for (area, name) and if you have performance problems when using the more general answers, you could experiment with joins - which the DB engine can sometimes optimize more than a correlated subquery:
select t2.*
from table2 t2
join table1 t1a on t1a.area = t2.area and t1a.name = 'sarah'
join table1 t1b on t1b.area = t2.area and t1b.name = 'Phillip';

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

Difference between ON and WHERE clauses in SQL table joins

select e.last_name, e.hire_date
from employees e join employees m
on (m.last_name = 'Davies')
and (e.hire_date > m.hire_date);
select e.last_name, e.hire_date
from employees e join employees m
on (m.last_name = 'Davies')
where (e.hire_date > m.hire_date);
select e.last_name, e.hire_date
from employees e join employees m
on (e.hire_date > m.hire_date)
where (m.last_name = 'Davies');
These three statements have the same result. Apart from the fact that where cannot be used exclusively, without using on, is there any particular reason to use where at all in table joins?
The main difference is when you are using different joins.
Typically you should see the same result if you were to use inner joins, but once you start using LEFT joins the results will change.
Have a look at the following example
SQL Fiddle DEMO
And have a look at the following article (very explanatory)
EDIT for #ShannonSeverance
Schema and Test data
CREATE TABLE Table1 (
ID INT,
Val VARCHAR(20)
);
INSERT INTO Table1 VALUES (1,'a');
INSERT INTO Table1 VALUES (2,'a');
CREATE TABLE Table2 (
ID INT,
Val VARCHAR(20)
);
INSERT INTO Table2 VALUES (1,'a');
and Tests
SELECT t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 INNER JOIN
Table2 t2 ON t1.ID = t2.ID AND t1.Val = t2.Val;
SELECT t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1,Table2 t2
WHERE t1.ID = t2.ID
AND t1.Val = t2.Val;
SELECT t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 LEFT JOIN
Table2 t2 ON t1.ID = t2.ID AND t1.Val = t2.Val;
SELECT t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 LEFT JOIN
Table2 t2 ON t1.ID = t2.ID
WHERE t1.Val = t2.Val;
where is a filter which is applied after rows are selected using the join. It is not always the case that a join ... on condition is sematically equivalent to a where condition. Therefore, yes, there is a particular reason to use a where in table joins: when it does the right thing.
...and by contrast, the ON condition executes as the join is being made. ON conditions for joins earlier in multi-table joins can cut off millions of unnecessary joins so are generally preferred if semantically correct
– Bohemian
Using on usually used for querying more than one table. When making that query, tables must have relationship each other, in general the same value in a specific fields.
on will connect that same value, for example:
**table1**:
id_name id_position name
1 1 john
2 2 doe
3 2 tom
4 3 hawkins
**table2**
id_position position
1 system analyst
2 programmer
SELECT t1.id_name, t1.name, t2.position
FROM table1 t1 LEFT JOIN table2 t2
ON t1.id_position = t2.id_position
-- RESULT:
id_name name position
1 john system analyst
2 doe programmer
3 tom programmer
4 hawkins NULL -- NO MATCH IN table 2
as we can see on will connect table1 and table2 that have same value id_position, so it is a little different from what you have been written above.
While where can be used in every query and not depends how many tables in that query. In general where is used for conditional thing that we want.
The difference lies in when the engine performs the filtering. A "where" represents a filter on the computed product of both tables. The "on" keyword specifies how a join is performed. They are not semantically equivalent even if sometimes they both produce the same outcome.
Cheers
The ON clause defines the relationship between the tables.
ON Clause supports all join types.
The WHERE clause describes which rows you are interested in.
WHERE Clause only supports for Inner join not for Outer joins like LEFT
JOIN and RIGHT JOIN.