how to get the table of missing rows in mysql - mysql

i have two mysql tables
tableA
colA1 colA2
1 whatever
2 whatever
3 whatever
4 whatever
5 whatever
6 whatever
second table is basically derived from tableA but has some rows deleted
tableB
colB1 colB2
1 whatever
2 whatever
4 whatever
6 whatever
how can i write an query to obtain the table of missing rows from the above two tables
i.e
colC1 colC2
3 whatever
5 whatever

SELECT t1.*
FROM TableA t1 LEFT JOIN
TableB t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL

What about something like this :
select *
from tableA
where not exists (
select 1
from tableB
where tableB.colB1 = tableA.coldA1
)
i.e. you select the data from tableA for which there is no equivalent data in tableB.

select * from tableA where colA1 not in ( select colA1 from tableB ) ;

Related

SQL to fetch data where Unique key matches but the data is different in some other columns between different tables

I have two tables of same structure as below. I am trying to write a query to compare both the tables using the Unique key which is the first column and trying to return values when there is a mismatch in the second column.
If the key is not present then no need to consider that data. only if the key is present in both the table then we have compare it.
Table A
ColumnA ColumnB
A 1
B 2
C 2
D 8
Table B
ColumnC ColumnD
A 1
B 3
C 5
F 4
For example the output of the above table when comparing Table A with B should be
B 2
C 2
and when comparing Table B with A it should be
B 3
C 5
Ideally the difference in the base table should come.
I have tried Joins and Unions but I am not able to fetch the data as mentioned above.
Since you want only those rows which has matching FK values in both the tables, we simply need to use INNER JOIN.
Now, we can simply consider the unmatching rows by using WHERE .. <> ..
When comparing Table A against Table B, we can get Table A rows only:
SELECT
tA.*
FROM tableA AS tA
JOIN tableB AS tB
ON tB.ColumnC = tA.ColumnA
WHERE tB.ColumnD <> tA.ColumnB
When comparing Table B against Table A, simply fetch the rows from Table B only:
SELECT
tB.*
FROM tableA AS tA
JOIN tableB AS tB
ON tB.ColumnC = tA.ColumnA
WHERE tB.ColumnD <> tA.ColumnB
I would do :
SELECT t.*
FROM tablea t
WHERE EXISTS (SELECT 1 FROM tableb t1 WHERE t1.cola = t.cola AND t1.colb <> t.cold);
Same would be for second version just need to swipe the table names.
use EXISTS and union all
SELECT t.*
FROM tablea t
WHERE EXISTS (SELECT 1 FROM tableb t1 WHERE t1.cola = t.cola AND t1.colb <> t.colb)
union all
SELECT t.*
FROM tableb t
WHERE EXISTS (SELECT 1 FROM tablea t1 WHERE t1.cola = t.cola AND t1.colb <> t.colb)

How to merge(columns) outputs of two SELECT statements in oracle sql?

I have two Select queries.
The first Select query gives the output which has two columns viz.
A B
------
1 2
3 4
5 6
7 8
The second Select query given the output which as two columns viz Column B and Column C. All the values in Column B of this select statement matches the values of Column B of the first Select statement.i.e
B C
------
2 25
4 50
6 30
8 50
Now, I need to merge the outputs of the above two Select queries. i.e
A B C
----------
1 2 25
3 4 50
5 6 30
7 8 50
I cannot use views to store the output of the two select queries. I need to use the Column B in both select queries to merge. However, I am not able to figure out how to go about it.
If you have elaborated queries (not just tables to join), you may try using with construction
with
Query1 as ( -- <- Put your 1st Query text here
select A,
B
...
),
Query2 as ( -- <- Put your 2nd Query text here
select B,
C
...
)
select Query1.A,
Query1.B,
Query2.C
from Query1,
Query2
where Query1.B = Query2.B
If your case is not that complicated, e.g. both Query1 and Query2 are in fact tables, say Table1 and Table2 you can do well with a simpler solution:
select Table1.A,
Table1.B,
Table2.C
from Table1,
Table2
where Table1.B = table2.B
Consider you tables like having fields like
TableA(A ,B) , TableB(B,C)
Try using JOIN like
SELECT TableA.A , TableA.B, TableB.C
FROM TableA
JOIN TableB ON TableA.B = TableB.B;
This can be accomplished by joining your first table to your second table using an INNER JOIN on the B column:
SELECT T1.A,
T1.B,
T2.C
FROM Table1 T1
INNER JOIN Table2 T2 ON T2.B = T1.B
Note that I called your first table Table1 (alias T1) and your second table Table2 (alias T2) as I was unsure of their names.
SELECT one.a, one.b, two.c
FROM table1 one JOIN table2 two
ON one.b = two.b
You can use Join
SELECT A.A,
A.B,
B.C
FROM Table1 A
INNER JOIN Table2 B ON B.B = A.B

Alternative to UNION clause in Mysql

I have two table :- table a, table b.
table a
---ID---
1
2
3
4
5
7
table b
---ID----
2
3
4
5
6
I have to get Output Like this without UNION Command:-
----ID-----
1
2
3
4
5
6
7
Note: I have one solution with union:-
**select * from a
UNION
select * from b;**
I need alternative to this. please experts suggest.
We need another table with (at least) 2 rows for this:
CREATE TABLE d
( id INT NOT NULL
);
INSERT INTO d
(id)
VALUES
(0), (1) ;
Then, if we want to have only one query, we can use (this is for fun, DO NOT USE in production, that's why we have UNION):
SELECT DISTINCT
COALESCE(aa.id, bb.id) AS id
FROM
d
LEFT JOIN a AS aa ON d.id = 0
LEFT JOIN b AS bb ON d.id = 1
WHERE
COALESCE(aa.id, bb.id) IS NOT NULL
ORDER BY
id ;
Tested at SQLfiddle.com, and for other table combinations:
1 row - 1 row
2 rows - 2 rows
0 rows - 1 row
0 rows - 2 rows
0 rows - 0 rows
try this:
I think it works well in MS-SQL, change it to MySQL if you need, but MYSql doesnot support full outer join! Good luck
SELECT (
CASE
WHEN b.ID IS NULL
THEN a.ID
WHEN b.ID=a.ID
THEN b.ID
ELSE b.ID
END)
FROM
(SELECT ID FROM table2
)b
FULL OUTER JOIN
(SELECT ID FROM table1
) a
ON a.ID=b.ID
and play around with the query
Fiddle: http://sqlfiddle.com/#!3/c657d/13
And here is the MYSQL version:
SELECT DISTINCT COALESCE(t1.id, t2.id) id
FROM
(
SELECT TABLE_NAME <> 'table_a' n
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = SCHEMA()
AND TABLE_NAME IN('table_a', 'table_b')
) t LEFT JOIN table_a t1
ON t.n = 0 LEFT JOIN table_b t2
ON t.n = 1
Working fiddle: http://sqlfiddle.com/#!2/c657d8/34
I don't know why you are avoiding UNION but you can do like following
CREATE TABLE temp_ids(ID INT);
INSERT INTO temp_ids SELECT ID FROM a;
INSERT INTO temp_ids SELECT ID FROM b;
SELECT DISTINCT ID FROM temp_ids;
Try a full outer join and filter the NULL values.
As an abstract exercise (if this is an interview question we expect a kickback!) one ugly, innefficient solution would be to create a cartesian product and filter the unique values:
SELECT DISTINCT IF(a<>b, b.id, a.id)
FROM a, b
ORDER BY 1
;
Use FULL OUTER JOIN, like this:
SELECT CASE
WHEN t1.id IS NULL THEN t2.id
ELSE t1.id
END AS id
FROM t1
FULL OUTER JOIN t2
ON t1.id = t2.id
ORDER BY id
Note: Mysql does not support full outer joins.
Working demo: http://sqlfiddle.com/#!6/b7684/10

select self join if only one resulting row

Is it possible/economical to perform a SELF JOIN of a table (for this example, my table called myTable has two columns pk and fk), and return a record if there is only one resulting record? I am thinking of something like the following, however, only_one_row() is a fictional function that would need to be replaced with something real:
SELECT fk
FROM myTable as t1
INNER JOIN myTable AS t2 ON t2.fk=t1.fk
WHERE t1.pk=1
AND only_one_row();
For instance, if myTable(id,fk) had the following records, only one record is produced, and I which to select the record:
1 1
2 1
3 2
However, if myTable(id,fk) had the following records, two '1' records are produced, and the select should not return any rows:
1 1
2 1
3 2
4 1
I could use PHP to do so, but would rather just use SQL if feasible.
Use a HAVING clause that counts the results.
SELECT fk
FROM myTable as t1
INNER JOIN myTable AS t2 ON t2.fk=t1.fk
WHERE t1.pk=1
HAVING COUNT(*) = 1
How about this:
SELECT fk
FROM myTable as t1
INNER JOIN myTable AS t2 ON t2.fk=t1.fk
WHERE t1.pk=1
GROUP BY fk
HAVING COUNT(fk) = 1

Mysql Query optimization

Below is my Table Structure
Table 1
id
name
Table 2
id
table1_id
I want the rows from table 1 which have no reference value in table 2.
Example data:
Table 1
id name
1 demo
2 demo2
3 demo3
Table 2
id table1_id
1 1
2 1
3 1
4 3
5 3
So there is no value in table 2 with table1_id 2. I want id 2 from Table 1.
Below id the query i have tried:
SELECT l.id FROM Table1 l WHERE l.id NOT IN (SELECT DISTINCT(r.id) FROM table2 r);
This is returning a proper result but its taking more than 2 minutes to process.
In table 1 i have 4000 rows and in table 2 I have 40000 rows.
Any optimisation to above query or any alternative solution?
SELECT * FROM table1 LEFT JOIN table2
ON table1.id=table2.table1_id
WHERE table2.table1_id IS NULL
Have an index for Table1.id and Table2.table1_id, then try the following query:
SELECT Table1.id FROM Table1
WHERE Table1.id NOT IN (SELECT Table2.id FROM Table2 group by Table2.table1_id);
What you are trying to acheive is to find orphan records right?
A join that shows all the records from the first(the left) table and the matching values form the other or nulls for no matches is called a left join. I think a left join will do the same job but it is not going to be any faster. Joins are in general slower.
I found a place where it is all well explained - http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/
It does not hurt to try with a join though, and tell us were your results the same as expected.
select t1.id from table1 as t1
left outer join table2 as t2
on t2.table1_id = t1.id
where t2.id is null;
or
select t1.id from table1 as t1
where not exists (select 1
from table2 as t2 where t2.table1_id = t1.id);