I have 5 tables in my Mysql database with t1 with field name like data,id,cool and 4 other tables with id and data say t2,t3,t4,t5.
I have used join and sub queries but result i am getting is empty set its not mandatory that all the fields in the t2,t3,t4,t5 tables are populated .t4,t5,t3,t2 can be empty i am using where clause on data if data column of t1 = t2 = t3 = t4 = t5 if it finds any matching data in any of the table it prints the cool from t1 and id and data from found table if any and if founds the data match in all the table it prints all the table stats like
cool data.t1 id.t1
cool data.t2 id.t2
and so on
table t1
cool data id
0 xyz 1
table t2
data id
xyz 5
table t3
data id
xyz 4
table t4
data id
xyz 3
table t5
data id
xyz 2
desired output
cool data id
0 xyz 1
0 xyz 4
0 xyz 3
0 xyz 5
0 xyz 2
if any of the table is empty say t5 and t4 than output should be
cool data id
0 xyz 1
0 xyz 4
0 xyz 3
What i understand from the question is you need to get data from table t1 for all other tables for all matching data and id column in respective table.
A simple way to achieve is to join each table with t1 seperately and then use union all to combine all results.
SELECT t1.cool, t2.data, t2.id
FROM t1 INNER JOIN t2 ON (t1.id=t2.id) AND (t1.data=t2.data)
UNION ALL
SELECT t1.cool, t3.data, t3.id
FROM t1 INNER JOIN t3 ON (t1.id=t3.id) AND (t1.data=t3.data)
UNION ALL
SELECT t1.cool, t4.data, t4.id
FROM t1 INNER JOIN t4 ON (t1.id=t4.id) AND (t1.data=t4.data)
UNION ALL
SELECT t1.cool, t5.data, t5.id
FROM t1 INNER JOIN t5 ON (t1.id=t5.id) AND (t1.data=t5.data)
as from your example, it is quite possible that there can be duplicate records To filter them out use distinct like this -
SELECT DISTINCT cool, data, id
FROM
(
-- above query here
)
Related
I've got two tables T1 and T2, both with a single field (id).
T1.id has values:
1
2
4
T2.id has values:
1
3
4
I need to join these tables.
Desired result:
T1 | T2
------|------
1 | 1
2 | null
null | 3
4 | 4
With JOIN I'd do it easily:
Query 1
SELECT * FROM T1 FULL JOIN T2 ON T1.id=T2.id
But due to certain reasons I can't use JOIN here. So, with a simple query like this
Query 2
SELECT * FROM T1, T2 WHERE T1.id=T2.id
I would get only two rows of data
T1 | T2
------|------
1 | 1
4 | 4
as two other rows would be omitted due to no matches in the other table.
No matter what to fill the missing matches with. It could be NULL or any other value - really anything, but I need to get those omitted rows.
Is there a way to modify Query 2 to get the desired result without using any JOIN?
PS: Real tables are different in structure, so UNION is not allowed either.
PPS: I've just given a model to point out the problem. In reality it's a "megaquery" involving many tables each having dozens of columns.
Standard way to implement FULL OUTER JOIN when only implicit joins are supported.
select t1.id t1id, t2.id t2id
from t1, t2 where t1.id = t2.id
union all
select id, null from t1
where not exists (select 1 from t2 where t2.id = t1.id)
union all
select null, id from t2
where not exists (select 1 from t1 where t1.id = t2.id)
order by coalesce(t1id, t2id)
The first SELECT produces the INNER JOIN part of the result.
The second SELECT adds the additional LEFT OUTER JOIN rows to the result.
The third SELECT adds the additional RIGHT OUTER JOIN rows to the result.
All together, a FULL OUTER JOIN is performed!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ec154ad243efdff2162816205fdd42b5
SELECT t1.id t1_id, t2.id t2_id
FROM ( SELECT id FROM table1
UNION DISTINCT
SELECT id FROM table2 ) t0
NATURAL LEFT JOIN table1 t1
NATURAL LEFT JOIN table2 t2
I have 3 tables
Table 1 - table1_id, title
Table 2 - table2_id, table1_id
Table 3 - table3_id, table2_id
Here Table 2 has reference of Table 1 there can be multiple Table 2 rows referring Table 1 and Table 3 is referring to Table 2 there can be multiple Table 3 rows referring to Table 2.
There is an one-many relationship between Table1-Table2 and Table2-Table3
Now I want the sum of all the rows in Table 3 with table1_id
Input- table1_id = "abc"
Output- 9
PS- Sorry for such abstract description , its quite difficult to explain here if needed I can add some more details.
SELECT t1.id, COUNT(t3.id), SUM(t3.amount)
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.table1_id
JOIN table3 t3 ON t2.id = t3.table2_id
GROUP BY t1.id
I have two tables.
table 1
1
2
3
4
table 2
1
2
3
i want to select data from tables
table 1 have all data.
but table 2 may have all data or not.
so
if table 1 data exits in table two data select table 2 data otherwise select table one data.
if table 1 data not exit table 2 select table 1 data.
how can do that?
You need OUTER JOIN:
SELECT t1.ID,
COALESCE(t2.col1, t1.col1) AS col1, -- prefer data from table_2 if exists
COALESCE(t2.col2, t1.col2) AS col2,
-- ...
FROM table_1 t1 -- "table 1 have all data"
LEFT JOIN table_2 t2 -- "table 2 may have all data or not"
ON t1.ID = t2.ID;
Try FULL OUTER JOIN
SELECT t2.col1, t1.col1
FROM
table_1 t1 FULL OUTER JOIN table_2 t2
ON t2.col1 = t1.col1
Or, if full joins are not supported by your database, try emulating them.
I would like to insert rows from one table products (table1) and column named text into a second table where the table doesn't have the same row values of the text2 columns using (like) i am referring to the wp_posts (table2) table.
First table: table1
id | text
-------------
1 t1
2 t2
3 t3
4 t4
5 t5
6 t6
7 t7
8 t8
....
Second table: table2
id | text2
--------------
1 t1
2 t4
3 t6 t62
4 t8
5 t9
...
Expected result after select:
id | text2
--------------
1 t2
2 t3
3 t5
4 t7
...
this result i want to insert in table2
Expected result after insert in tabel2:
id | text
-------------
1 t1
2 t2
3 t3
4 t4
5 t5
6 t6 t62
7 t7
8 t8
9 t9
....
and this result i want to inser in tabel 2 where these values are missing.
I tried something like this, but because the data tables have a large amount of that in them, more then 180000 entries, this takes a long time:
INSERT INTO table2 (text2)
SELECT t1.text,
FROM table1 t1
JOIN table2 t2 ON t1.text LIKE CONCAT('%', t2.text2 ,'%')
Or how do i do something like this?:
SELECT text
FROM tabel1
WHERE NOT EXISTS (SELECT text2
FROM tabel2
WHERE text2 LIKE tabel1.text ????)
Or other idea to solve this problem?
I would use your first query, but your logic is back to front: you are selecting the rows that are present, not the ones that aren't.
Try this:
INSERT INTO table2 (text2)
SELECT t1.text,
FROM table1 t1
LEFT JOIN table2 t2 ON t1.text LIKE CONCAT('%', t2.text2 ,'%')
WHERE table2.text2 IS NULL
This left join will select all rows that don't match, because columns of missed joins are all null.
Regarding performance, this query is about as good as it gets, but your can make it run faster by starting a transaction, locking the target table, running the query then committing.
If that isn't fast enough, try exporting the query results then importing them into the target table in a separate step.
Assuming both your tables have unique keys on ID field...
insert into table2 (id, text2)
select id, text from table1
on duplicate key update
text2=concat_ws(' ',text2, values(text2));
UPDATE:
more elaborated variant to remove duplicates (Assuming the text from table1 describes unique items):
insert into table2 (id, text2)
select id, text from table1
on duplicate key update
text2=if(find_in_set(values(text2),replace(text2,' ',','))>0,
text2,concat_ws(' ',text2, values(text2)));
See difference between the two statements on SQL Fiddle: first one vs second one.
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);