Compare two table and find missing row - mysql

I have two simple tables:
table1 :
id , h_id, role, l_name
1 , 2, 3, test1
1, 2, 4, test1
table2 :
id , h_id, role, l_name
1 , 2, 3, test1
1 , 2, 3, test2
we do not have any primary or foreign key to compare. there are chances that id , h_id, role, might have same data in both table but l_name could be different. it cloud be other column as well.
what is best way to compare for above scenario?

If I understood your case, you would be able to isolate data doesn't match from both table1 and table2 ? Is this ? So you can try this query :
select t1.id, t1.h_id,t1.role, t1.l_name, t2.id, t2.h_id,t2.role,
t2.l_name from table1 t1
left join table2 t2
on t1.id = t2.id and t1.h_id =t2.h_id and t1.role=t2.role and t1.l_name=t2.l_name
where t2.id is null
union
select t2.id, t2.h_id, t2.role, t2.l_name, t1.id, t1.h_id, t1.role,
t1.l_name from table1 t2
right join table2 t1
on t1.id = t2.id and t1.h_id = t2.h_id and t1.role=t2.role and t1.l_name = t2.l_name
where t2.id is null;

I would use the MINUS operator:
Select * from table1
Minus
Select * from table2
And repeat the other way

Related

How to get unique (not vice-versa) fields on MySQL

The title may be misleading but i don't know how to formulate it better.
Suppose i have these rows on my MySQL table:
table1:
id column1 column2
1 1 2
2 1 3
3 2 1
4 3 4
I have written a query to retrieve data that have similar vice-versa values on columns column1 and column2 (id: 1 & id: 3), but I'm having trouble querying over data that don't have similar vice-versa rows (id: 2 & id: 4) or that are sort of unique.
EDIT: The query i've used to get vice-versa rows
SELECT * FROM table1 t1
INNER JOIN table1 t2
ON (t1.column1 = t2.column2 AND t1.column2 = t2.column1);
You could use exists logic here:
SELECT id, column1, column2
FROM yourTable t1
WHERE NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE LEAST(t2.column1, t2.column2) = LEAST(t1.column1, t1.column2) AND
GREATEST(t2.column1, t2.column2) = GREATEST(t1.column1, t1.column2));
A simple solution would be to use your query in the WHERE clause to filter out similar rows:
SELECT *
FROM table1 t1
WHERE (column1, column2) NOT IN
(SELECT t1.column1, t1.column2
FROM table1 t1
INNER JOIN table1 t2
ON t1.column1 = t2.column2 AND t1.column2 = t2.column1)
Demo here

How to remove common records found in 2 tables?

For example:
table 1
x y
2 3
1 2
8 9
table 2
x y
2 3
8 9
So here I need to remove the common field found in both the table
result should be
Result
x y
1 2
only i should get a unique row
You can use NOT EXISTS :
SELECT t1.*
FROM table1 t1
WHERE NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.X = t1.X AND t2.Y = t1.Y);
You can also use NOT EXISTS operator which is more efficient as it also considers NULL values while comparison.
select * from table1 A
where not exists (select name from table2 B where A.name=B.name)
Try this:
Demo 1
Demo 2
select x, y
from
(
select x, y
from table1
union all
select x, y
from table2
) i
group by x, y
having count(*) = 1
Assuming the task is "delete duplicated record from BOTH TABLES accounting NULLs":
DELETE t1.*, t2.*
FROM table1 t1
JOIN table2 t2 ON t1.x <=> t2.x
AND t1.y <=> t2.y;
fiddle
Assuming the task is "delete duplicated record from both tables NOT accounting NULLs":
DELETE t1.*, t2.*
FROM table1 t1
JOIN table2 t2 USING (x, y);
fiddle
If the task is "delete duplicated record from one table and store them in another table" then edit DELETE t1.*, t2.* and store only those table which records must be deleted, for example, DELETE t1.*.
Assuming this is to remove duplicate from a table that exist in another table
if all colums have non null value then:-
DELETE t1
FROM tbl_test_1 t1
INNER JOIN tbl_test_2 t2
ON t1.col_1 = t2.col_1
AND t1.col_2 = t2.col_2
WHERE t2.id is not null
Here if a particualr coulm from both table are NULL , we miss that.
So to catch colm match with NULL as well, try this:-
#to check before deletion
SELECT * ,
concat_ws("_",COALESCE(t1.col_1, 'null'),COALESCE(t1.col_2, 'null')),
concat_ws("_",COALESCE(t2.col_1,'null'),COALESCE(t2.col_2,'null'))
FROM tbl_test_1 t1
left JOIN tbl_test_2 t2
ON concat_ws("_",COALESCE(t1.col_1, 'null'),COALESCE(t1.col_2, 'null'))= concat_ws("_",COALESCE(t2.col_1, 'null'),COALESCE(t2.col_2, 'null'))
WHERE t2.id is not null
delete query
#delete query
DELETE t1
FROM tbl_test_1 t1
left JOIN tbl_test_2 t2
ON concat_ws("_",COALESCE(t1.col_1, 'null'),COALESCE(t1.col2, 'null'))= concat_ws("_",COALESCE(t2.col_1, 'null'),COALESCE(t2.col2, 'null'))
WHERE t2.id is not null

Join two tables based on a view, sql

I have the following sql situation
Table1
id name
Table2
id name
_Table1ToTable2
id, id_table1, id_table2
Result:
id, name, table2_name, table2_id
I would like to join Table1 and Table2 into a single query, but I cannot find a way to make a join between them, any ideas?
It seems like you want to use bridge table Table1ToTable2 to join Table1 and Table2. This can be done simply with 2 INNER JOINs :
SELECT
tt.id AS tt_id,
t1.id AS t1_id,
t1.name AS t1_name,
t2.id AS t2_id,
t2.name AS t2_name
FROM
Table1ToTable2 AS tt
INNER JOIN Table1 AS t1
ON t1.id = tt.id_table1
INNER JOIN Table2 AS t2
ON t2.id = tt.id_table2
if there is no relationship between table1 and table 2 then,
select table1.id, table1.name, table2.id, table2.name from
table1, table2
if table1 and table2 are related with ID then,
select table1.id, table1.name, table2.id, table2.name from
table1
inner join table2
on table1.id = table2.id
If your intention is to retrieve a result set with every possible combination of the id columns from both tables then you can do as follows:
select id = identity (int, 1, 1), * into #a from (select distinct table1. id as id1, table2. id as id2 from table1 cross apply table2) d; select * from #a; drop table #a
If you do not wish to use a temp table an alternative would be to use some variation of the row_number() function.
The above solves for an assumed requirement as your question lacks context. Elaborate on your requirements and we will be able to provide you with a more relevant and detailed answer.

Form a query to get the difference in two tables with a common column

I have two tables.One with original data (t1) and the other with altered data after some operation is performed (t2). The structure of the two tables is same (Columns - GUID, ID, Value). GUID, ID form the Primary Key.
GUID and ID will remain same after the operation. However, some IDs (in t1) may be absent in t2 and some may be added in t2.
Sample -
t1 t2
GUID ID Value GUID ID Value
(i) 1 a x 1 a x --> same
(ii) 1 b y 1 b w --> VALUE different
(iii) 2 a x --> extra ID in t1
(iv) 2 b z --> extra ID in t2
My goal is to print the difference in t1 and t2 in the following format (new table)
Difference
GUID ID Value1 Value2
(ii) 1 b y w --> VALUE different
(iii) 2 a x NULL --> extra ID in t1
(iv) 2 b NULL z --> extra ID in t2
My try -
I have split the problem into 3 parts.
Insert rows whose values are different
INSERT INTO Difference(GUID,ID,Value1,Value2)
SELECT t1.GUID, t1.ID, t1.Value, t2.Value from t1, t2
WHERE t1.GUID = t2.GUID and t1.ID = t2.ID and t1.Value != t2.Value
The above query returns correct values.
Insert rows with IDs present in t1 and not present in t2.
I want to use a query like this ->
INSERT INTO Difference(GUID,ID,Value1)
(SELECT t1.GUID, t1.ID, t1.Value from t1, t2
WHERE t1.GUID= t2.GUID and t1.ID IN
((SELECT GUID,ID FROM t1 ) EXCEPT
(SELECT GUID,ID FROM t2 ))) // I get an error here.
Error :- Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I know I should select only "ID" column for IN clause. But that doesn't satisfy the condition. I want to use both GUID and ID in the 'IN' clause. I tried a number of other queries that didn't work. What should I do to get this result?
Same as 2nd with tables reversed.
you can union t1 joining t2 and t2 joining t1 and group by two columns key to allow only one record from their intersection
SELECT
x.GUID,
x.ID,
x.Value1,
x.Value2
FROM (
SELECT t1.GUID, t1.ID, t1.Value AS Value1, t2.Value AS Value2 FROM t1 LEFT JOIN t2 ON t2.GUID = t1.GUID AND t2.ID = t1.ID
UNION ALL
SELECT t2.GUID, t2.ID, t1.Value AS Value1, t2.Value AS Value2 FROM t2 LEFT JOIN t1 ON t1.GUID = t2.GUID AND t1.ID = t2.ID
) x
GROUP BY x.GUID, x.ID;

Conditional SELECT SQL with relational tables

Say I have an id in table1 which is a foreign key in table2 and there is a column in table2 called condition.
I need to select all ids from table 1 that aren't in table2 where condition = 1.
So for id in table 1 "select it" if it is not in table2 where condition = 1.
Edit: I used Ahsan Habib's answer and it worked great!
if you just want to select ID column from table1 this will work fine....Its just a simple set operation
select id from t1
minus
select id from t2 where condition = 1;
for all column you may try
select * from t1 whare id not in (select id from t2 where condition = 1);
This is almost a direct translation of what you are asking for:
select t1.*
from table1 t1
where t1.id not in (select t2.id from table2 t2 where t2.condition = 1);
Another way using NOT EXISTS
select t1.*
from table1 t1
where NOT EXISTS(select 1 from table2 t2 where t1.id = t2.id and t2.condition = 1);