Comparing Two SQL Tables Based On Matching Column - sql

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);

Related

SAS SQL inner join two columns able to match one column

How can I do something like select * from T1 inner join T2 on (T1.ID=T2.ID OR T1.ID2=T2.ID)
When I execute this code, it seems to fall in a infinity loop so I guess I'm wrong.
In other words, how can I match one of two columns from T1 to one column from T2
T1
ID ID2
1 10
2 20
T2
ID value
1 dummy10
20 dummy20
Result
ID ID2 value
1 10 dummy10
2 20 dummy20
Try to do like this:
select *
from T1, T2
where T1.ID = T2.ID or T1.ID2 = T2.ID
you can use 2 select statements with union, like this:
select
t1.ID,
t1.ID2,
t2.value
from Table1 as t1
inner join Table2 as t2 on t1.ID = t2.ID
UNION
select
t1.ID,
t1.ID2,
t2.value
from Table1 as t1
inner join Table2 as t2 on t1.ID2 = t2.ID
/* this will exclude values selected by other statement */
where t1.ID2 not in (select ID2 from Table1 inner join Table2 on Table1.ID = Table2.ID)
The only issue I can see with the code you provide is that you have not specified from which table you want the common column ID to be selected:
proc sql;
select
t1.*
,t2.value
from t1
inner join t2
on t1.id = t2.id or t1.id2 = t2.id;
quit;
Otherwise, your code should work. Perhaps the size of the data being joined is the problem?

Join tables based on condition in Hive

I have two tables and have mentioned the layout of tables in the below screenshot.
Using Id column I need to join two tables. Whenever there is a match with Id (example Id is a2), I need to take the corresponding values from Table2. In some scenario, Id from Table1 will not be there in Table2 (example Id is a1). In that case, I have to take values from Table2 where the value of Id in Table2 is all.
For better clarification, I have mentioned the Expected output in the below screenshot.
I tried the below code, but don't seem to be working.
select distinct t1.Id,t1.Name,t2.Phone1,t2.Phone2
from Table1 t1
left join Table1 t2 on t1.Id = case when t2.Id is null then t1.Id else t2.Id end
Any help is greatly appreciated.
You can use two left joins, where the second brings in the default values:
select t1.*, coalesce(t2.phone1, t2d.phone1) as phone1, coalesce(t2.phone2, t2d.phone2) as phone2
from table1 t1 left join
table2 t2
on t1.id = t2.id left join
table2 t2d
on t2d.id = 'All' and t2.id is null;

Combine two tables on same columns

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

Null<> Number displays nothing even if for id we have null in one and number in other

Sorry if this is very basic.
Here is what i noticed
Here are the tables:
Table1 Table2
ID Value ID Value
1 (null) 1 0
2 2 2 2
3 (null) 3 3
So i used the following statement:
Select T1.ID,T1.Value,T2.value
from
Table1 T1,
Table2 T2
where
T1.ID=T2.ID
and T1.Value<>T2.Value;
I was expecting the output to show 1,3 ID but it showed nothing not i am confused suppose i want to see all values when one table has null for other table value how can i do that.
Well, the problem is that comparisons to NULL always result in FALSE, except for IS NULL. So the clause should be:
where T1.ID=T2.ID and
coalesce(T1.Value, t2.value - 1) <> coalesce(T2.Value, t1.value -1);
Or something that matches the NULL values.
By the way, you should also use proper join syntax. So, the query should look more like:
Select T1.ID,T1.Value,T2.value
from Table1 T1 join
Table2 T2
on T1.ID=T2.ID and
((T1.Value <> T2.Value) or
(t1.value is not null and t2.value is null) or
(t1.value is null and t2.value is not null)
);
you have to use LEFT JOIN rather than INNER JOIN because you want to find non matching values.
Select t1.ID,T1.Value,T2.value
from Table1 T1
LEFT JOIN Table2 T2
ON T1.ID=T2.ID AND
t1.value = t2.value
where t2.value IS NULL
SQLFiddle Demo
To fully gain knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Select T1.ID,T1.Value,T2.value
from
Table1 T1,
Table2 T2
where
T1.ID=T2.ID
and (T1.Value<>T2.Value OR (T1.Value IS NULL AND T2.Value IS NOT NULL) OR (T2.Value IS NULL AND T1.Value IS NOT NULL));
Null values are special. You can do it with a complex query like
Select T1.ID,T1.Value,T2.value
from
Table1 T1,
Table2 T2
where
T1.ID=T2.ID
and ((t1.value is null or t2.value is null)
and !(t1.value is null and t2.value is null)
or t1.value <> t2.value);
Link to SQLFiddle
Note that the syntax is going to be different, depending on the flavor of SQL that you are using.

Join query between 2 tables, the first with several fields refering to the same fields in the other

I have to build an application on an existing SQL database and I came upon this situation.
There's a table (call it T1) where several fields reference values from another table (T2), which basically is made up of just 2 fields, Id and Name. As a consequence, T2 holds data of different nature and meaning, because the fields in T1 that relate to it are of very different kinds. (This seems to me an unusual design.)
My question: given this design, how I can build a join query in order to get the value of T2.Name related to each T1 field.
EDIT
I could get what I want by doing one query per field:
SELECT t2.name AS name1
FROM t1
INNER JOIN t2
ON t1.field1 = t2.id;
SELECT t2.name AS name2
FROM t1
INNER JOIN t2
ON t1.field2 = t2.id;
SELECT t2.name AS name3
FROM t1
INNER JOIN t2
ON t1.field3 = t2.id;
But this is nonsense. So how could I pack all this in one single query?
You need to alias references to t2 to get corresponding names:
SELECT alias1.name AS name1,
alias2.name AS name2,
alias3.name AS name3
FROM t1
INNER JOIN t2 alias1
ON t1.field1 = alias1.id
INNER JOIN t2 alias2
ON t1.field2 = alias2.id
INNER JOIN t2 alias3
ON t1.field3 = alias3.id;
You might want to replace inner with left joins if foreign keys are nullable.
Is there any reason you can't use ORs in your join? So:
SELECT t2.name AS name3
FROM t1, t2
WHERE t1.field1 = t2.id
OR t1.field2 = t2.id
OR t1.field3 = t2.id;
If for some reason you cant then you can use UNION to combine the result of all the queries in a single query. I don't know which RDBMS your using but for postgres you can find information here:
http://www.postgresql.org/docs/8.3/static/queries-union.html
For any other a quick google of the DBMS name and "UNION" should give you what you need.
Without seeing the table structures, you could do something like this:
SELECT t1.col1,
t1.col2,
t1.id as t1_id,
t2.id as t2_id,
t2.name as t2_name
FROM t1
INNER JOIN t2
ON t1.id = t2.id
Since you are joining the tables, you will just give a different alias for the columns that appear in both tables.
Based on your update, you should be able to consolidate those 3 queries into one:
SELECT t2.name AS name1
FROM t1
INNER JOIN t2
ON t1.field1 = t2.id
OR t1.field2 = t2.id
OR t1.field3 = t2.id
try something like this,
SELECT t2.name AS name1,
(case when t1.field1 = t2.id then 'Type1' when t1.field2=t2.id then 'Type2' else 'Type3' end) as Type FROM t1 INNER JOIN t2 ON t1.field1 = t2.id or
t1.field2=t2.id or t1.field3=t2.id