How to merge two tables keeping rows from first table - mysql

I have following two tables:
table1(a,b,c,d)
table2(a,b,c,d)
My requirement is to merge the two tables; if there are row(s) for combination of columns a and b (only combination of columns a and b, i.e, values for a and b are same) in both tables, keep the rows from first table.
I hope I am clear. Please suggest a query.
Note: Both tables don't have a primary key.
Thanks,
Update:
Left join on 's1.a = s2.a AND s1.b = s2.b' giving me duplicate rows and not picking the values from second table where column a and b values are not same. For example if I have 2 rows in table1 as:
11,22,33,44 --
11,55,33,44
and 2 rows in table2 as:
11,22,33,44 --
66,77,44,88
output is 4 rows as:
11,22,33,44 --
11,22,33,44 --
11,55,33,44 --
11,55,33,44
Update:
but output should be:
11,22,33,44 --
11,55,33,44 --
66,77,44,88
I thing I need UNION + JOIN + GROUP BY combination here but unable to come up with a right combination/query.

SELECT s1.* FROM
(SELECT a,b,c,d FROM table1) s1
LEFT JOIN
(SELECT a,b,c,d FROM table2) s2
ON s1.a = s2.a AND s1.b = s2.b
UPDATE:
SELECT a,b,c,d FROM table1 GROUP BY a,b,c,d
UNION
SELECT a,b,c,d FROM table2 GROUP BY a,b,c,d

Related

MySQL: How to SELECT a row from the 1st table if there is no matching row in the 2nd table

Table 1(number primary key):
id-1, number-123, name-asd
id-2, number-124, name-asd
Table 2(number can be duplicated, id pk):
id-1, number-123, name-asd
id-2, number-123, name-das
id-3, number-124, name-rrr
id-4, number-124, name-asx
Wanted output:
124, asd
I have to compare the 1st table rows with the rows in 2nd table.
If row 1 is not equal to each row in the second where a.number = b.number then we should execute select * from table1.
If we find a matching row (between table 1 and table 2) then we should not execute the select query found above.
UPDATE:
How can I compare 3 tables like that?
A simple select left joining the two tables, and filtering for rows where there is no data for the 2nd table should give your desired results.
SELECT *
FROM table1 a
LEFT JOIN table2 b
ON a.number = b.number AND a.name = b.name
WHERE b.id IS NULL

Advanced Mysql Query to get master record if two conditions matches on different rows of child records

I was writing a mysql filter query which has a primary table and another table which holds multiple records against each record of primary table (I will call this table child).
Am trying to write a query which fetches record of primary table based on its values on child table. If the child table condition is one then I will be able to do it simply by joining, but I have 2 conditions which falls on same field.
For ex.
table 1:
id name url
1 XXX http://www.yahoo.com
2 YYY http://www.google.com
3 ZZZ http://www.bing.com
table 2:
id masterid optionvalue
1 1 2
2 1 7
3 2 7
4 2 2
5 3 2
6 3 6
My query has to return unique master records when the optionvalue matches only both 2 different conditions match on second table.
I wrote query with IN...
select * from table1
left join table2 on table1.id=table2.masterid
where table2.optionvalue IN(2,7) group by table1.id;
This gets me all 3 records because IN is basically checking 'OR', but in my case I should not get 3rd master record because it has values 2,6 (there is no 7). If I write query with 'AND' then am not getting any records...
select * from table1
left join table2 on table1.id=table2.masterid
where table2.optionvalue = 2 and table2.optionvalue = 7;
This will not return records as the and will fail as am checking different values on same column. I wanted to write a query which fetches master records which has child records with field optionvalues holds both 2 and 7 on different records.
Any help would be much appreciated.
Indeed, as AsConfused hinted, you need to two joins to TABLE2 using aliases
-- both of these are tested:
-- find t1 where it has 2 and 7 in t2
select t1.*
from table1 t1
join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7
-- find t1 where it has 2 and 7 in t2, and no others in t2
select t1.*, ovx.id
from table1 t1
join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7
LEFT OUTER JOIN table2 ovx on t1.id=ovx.masterid and ovx.optionValue not in (2,7)
WHERE ovx.id is null
You can try something like this (no performance guarantees, and assumes you only want exact matches):
select table1.* from table1 join
(select masterid, group_concat(optionvalue order by optionvalue) as opt from table2
group by masterid) table2_group on table1.id=table2_group.masterid
where table2_group.opt='2,7';
http://sqlfiddle.com/#!9/673094/9
select * from t1 where id in
(select masterid from t2 where
(t2.masterid in (select masterid from t2 where optionvalue=2))
and (t2.masterid in (select masterid from t2 where optionvalue=7)))
Old school :-) Query took 0.0009 sec.
This can also be done without the joins using correlated exists subqueries. That may be more efficient.
select *
from table1
WHERE EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 2)
AND EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 7)
If this is to be an exclusive match as suggested by, "when the optionvalue matches only both 2 different conditions match on second table" then you could ad yet a third exists condition. Performance-wise this may start to break down.
AND NOT EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid AND optionvalue NOT IN (2,7)
Edit: A note on correlated subqueries from Which one is faster: correlated subqueries or join?.

how to fetch records from two different tables with no unique fields

i have two different tables like table1 and table2. There is no relationship between them.
now i want to retrieve two different fields like field1 from table1 and field2 from table2 using a single query .
select field1,group_concat(field2) from table1,table2. when i use this query data successfully comes if the 2nd table has rows, otherwise all data are null
The way to do this is to use a cross join. Beware that this will result in lots of duplicate data though.
For example, if the tables have the following data:
Table 1
Field 1
1
2
3
Table2
Field 2
A
B
C
The cross join (eg select table1.field1, table2.field2 from table1 cross join table2) will return:
Field 1, Field 2
1, A
2, A
3, A
1, B
2, B
3, B
1, C
2, C
3, C
As each table has three rows, the cross join returns 3 x 3 = 9 rows. If your tables have, for example, 100 rows each, the query will return 100 x 100 = 10,000 rows. As you can see, the amount of data returned can quickly get out of hand with a cross join.
Since there is no relationship between the two tables, you are likely better off with two queries.
SELECT tableA.row1,tableA.row2,tableB.row1, tableB.row2
FROM tableA
CROSS JOIN tableB;
It depends on what is exactly there in the data. If both the fields are of same type you could take a look at UNION. So the overall query will be like
(SELECT field1 FROM table1) UNION (SELECT field2 FROM table2);
Else if you want a cross product of the two fields (since there is no relationship between them) you could use JOIN
SELECT field1,field2 FROM table1 JOIN table2;

mysql union of 2 tables

I have 2 tables:
table A (id, user_id, flag)
table B (id, user_id, flag)
Here If I take Count of table A it comes as 10 and that of B 5
So Total = 10 + 5 = 15.
SELECT * FROM table A
LEFT JOIN table B ON table B.user_id = table A.user_id
UNION ALL
SELECT * FROM table A
RIGHT JOIN table B ON table B.user_id = table A.user_id
So It should Come 15 instead it showing 50.
use
SELECT * FROM TABLE1 UNION
SELECT * FROM TABLE2
UNION removes duplicate records in other hand UNION ALL does not.Check HERE
You need to make sure the data in your tables are correct.
Table A Should have 15 rows
SELECT COUNT(*) as 'rowCountTableA' FROM table_a;
Table B Should have 5 rows
SELECT COUNT(*) as 'rowCountTableB' FROM table_b;
If your tables are correct and have exactly matching column names you can join them together by specifying asterisks to get all column values.
If however the columns in your table have a few different column names that are in table_a that are not in table_b you must call out the column names instead of using asterisk to get all values.
EXAMPLE:
SELECT (id,user_id,flag) FROM table_a
UNION ALL
SELECT (id,user_id,flag) FROM table_b

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