I have the following three tables...
Table1
IDA colB colC
111 a w
222 b w
333 c s
444 b g
Table2
IDB colB colC
11 w f
12 w r
13 s g
Table3
IDA IDB
111 11
222 12
333 13
444 14
What I need is to copy from table1 to table2 and I could use the following easy MySQL query to do that...
INSERT INTO table2 SELECT * FROM table1
The problem is I don't the same id type,...the two tables are connected over the third table table3.
in which IDA contains table1 primary key and IDB contain table2 primary key,
so, example if I want to copy from table1 IDA(111) to table2 how do I do that?
and if the IDB exists how do I update on Duplicate Key...
I have the following query but no working...
INSERT INTO table2 SELECT * FROM table1
WHERE IDA IN ( SELECT table1 b
INNER JOIN table3 c ON c.IDA = b.IDA
INNER JOIN table2 a ON a.IDB = c.IDB )
WHERE b.IDA=111
But, I wish if I get generalize answer...Thanks
INSERT INTO table2
SELECT
t3.idb
,t1.colb as ncolb
,t1.colc as ncolc
FROM
table1 t1
join table3 t3
on t1.ida = t3.ida
ON DUPLICATE KEY UPDATE
colb = ncolb
,colc = ncolc
No MySQL on me right now so syntax might not be 100% correct, but this should give you the idea of how it should be done.
Depending on whether table3 has entry for each table1 id you might need to change t3.idb to coalesce(t3.idb, t1.ida) and change join to left join in the query if you want them to be copied. Remember that table2 will then have ids from table1)
INSERT INTO table2 SELECT * FROM table1
WHERE IDA IN ( SELECT * FROM table1 b
INNER JOIN table3 c ON c.IDA = b.IDA
INNER JOIN table2 a ON a.IDB = c.IDB ) HAVING b.IDA=111
Related
I have two tables table1 and table2. A third table, table3, relates these two tables such that every record in table3 is the primary key, a foreign key to table1, and a foreign key to table2.
I have a selection of table2, and want to find all records in table1 which have a corresponding record in table3 for each of the records selected form table2
Table1
a
b
c
Table2 Selection
1
2
3
Table3
fk1
fk2
a
1
a
2
b
1
b
2
b
3
c
2
c
3
c
4
In this example, I want to find record b but not record a or c
I can make a join with:
select *
from table3
inner join table1
inner join table2 on table3.fk1=table1.id and table3.fk2=table2.id
where *table2 selection criteria*
But that just gives me everything in one table, I don't know how to require that you match ALL members of the selection, instead of any member
select eveonline_evecharacter.*
from eveonline_evecharacter
inner join mechanicus_characterskillmap on eveonline_evecharacter.id = mechanicus_characterskillmap.character_id
inner join mechanicus_skill on mechanicus_skill.id = mechanicus_characterskillmap.skill_id
inner join mechanicus_blueprintskill on mechanicus_blueprintskill.skill_id = mechanicus_skill.id
inner join mechanicus_blueprintoutput on mechanicus_blueprintoutput.blueprint_id=mechanicus_blueprintskill.blueprint_id
inner join mechanicus_item on mechanicus_item.id = mechanicus_blueprintoutput.item_id
where mechanicus_item.name = "Small Trimark Armor Pump I"
group by eveonline_evecharacter.id
having count (*) = (select count(*) from mechanicus_skill
inner join mechanicus_blueprintskill on mechanicus_blueprintskill.skill_id = mechanicus_skill.id
inner join mechanicus_blueprintoutput on mechanicus_blueprintoutput.blueprint_id=mechanicus_blueprintskill.blueprint_id
inner join mechanicus_item on mechanicus_item.id = mechanicus_blueprintoutput.item_id
where mechanicus_item.name = "Small Trimark Armor Pump I");
Get the count of the joined rows and compare this with the count of all the rows in table 2.
SELECT t1.*
FROM table1 AS t1
JOIN table3 AS t3 ON t3.fk1 = t1.id
JOIN table2 AS t2 ON t3.fk2 = t2.id
WHERE *some condition on table 2*
GROUP BY t1.id
HAVING COUNT(*) = (
SELECT COUNT(*) FROM table2 WHERE *some condition on table 2*
)
This assumes that all the IDs in table1 and table2 are unique, and all the pairs are unique. If not, use HAVING COUNT(DISTINCT t1.id) = (SELECT COUNT(DISTINCT id) FROM table2).
I have three tables with following data
Table 3 :
Table1_id Table2_id
1 1
1 2
1 3
2 1
2 3
3 2
Table 2 :
Table2_id Name
1 A
2 B
3 C
Table 1 :
Table1_id Name
1 P
2 Q
3 R
I have a problem where I need to return all table1_id's which have an entry for all Table2_ids's in Table 3.
ie. I want my output to be
Table1_id
1
I found a solution using count().
But is there a way to use all() or exists() to solve the query?
Using NOT IN with excluding LEFT JOIN in a subselect with a CROSS JOIN
select *
from table1
where Table1_id not in (
select t1.Table1_id
from table1 t1
cross join table2 t2
left join table3 t3 using (Table1_id, Table2_id)
where t3.Table1_id is null
)
VS using COUNT()
select table1_id
from table3
group by table1_id
having count(1) = (select count(1) from table2)
Explanation:
The CROSS JOIN
select t1.Table1_id
from table1 t1
cross join table2 t2
represents how table3 would look like, if every item from table1 would be related to every item from table2.
A (natural) left join with table3 will show us which relations really exists. Filtering by where t3.Table1_id is null (excluding LEFT JOIN) we get the missing relations. Using that result for the NOT IN clause, we get only table1 items that have no missing relation with table2.
You can use the following query:
SELECT DISTINCT t1.*
FROM Table2 AS t2
CROSS JOIN Table1 AS t1
WHERE NOT EXISTS (SELECT 1
FROM Table3 AS t3
WHERE t1.Table1_id = t3.Table1_id AND
t2.Table2_id = t3.Table2_id)
to get Table1 records not having a complete set of entries from Table2 in Table3. Then use NOT IN to get the expected result.
Here is a solution using EXISTS and INNER JOIN.
SELECT DISTINCT t3_out.Table1_id FROM Table3 t3_out
WHERE EXISTS( SELECT 1
FROM Table2 t2 INNER JOIN Table3 t3 ON t2.Table2_id = t3.Table2_id
WHERE t3.Table1_id = t3_out.Table1_id
HAVING COUNT(DISTINCT t2.Table2_id) = 3 )
Well, I have 2 tables like this:
Table1
ID | USER_ID
1 0
2 2
3 15
4 16
Table2
ID | FROM | TO
9 0 2
9 2 16
9 16 15
9 15 0
10 15 2
What I want is really simple but driving me crazy, considering that ID , FROM and TO represents users in table 2. I want to get someone in FROM (which is Table1.user_id) with an ID in table2 such as it also exists in TO (which is the same Table1.user_id) with the same ID of table2
For example, record 16 is eligible. Because it appears in From with ID of 9 and as TO with the same ID of 9 in table 2 (both TO and FROM correspond to a user_id of 15 in table1)
What I have done was:
select *
from `Table1`
where exists (select ID from `Table2` as p1 where FROM = 16)
and exists (select ID from `Table2` as p2 where ID = 16)
and p1.ID = p2.ID
You could try using a self join to find records with the same ID and then compare the values.
select a.from from table1 a inner table1 b on a.id = b.id
where a.from = b.to
This may work;
select * from table1 a where a.USER_ID in
(select b.FROM from table2 b
where exists (select c.id from table2 c
where b.id = c.id and b.FROM = c.TO) )
Is this what you want?
select *
from table1 t
where exists (select 1 from table2 t2 where t2.`from` = t.id) and
exists (select 1 from table2 t3 where t3.`to` = t.id);
I am not sure If understand it correctly.
If User_ID from Table_1 should be present in From AND in To columns from Table_2 AND for those records also ID in Table_2 must be same,
Then for those condition will be eligible not only User_ID 16 and 15 as you mentioned in your example but also for 0 and 2.
Assuming that is correct.
Then try this code (for mySQL you probably have to change some syntax):
SELECT A.*
FROM Table_1 AS A
INNER JOIN Table_2 AS B ON (A.USER_ID=B.FROM)
INNER JOIN Table_2 AS C ON (A.USER_ID=C.TO AND C.ID = B.ID)
table1
cid
itemdesc
itemprice
table2
cid
imagename
status
My 1st table is has unique cid (no duplicate) I want it to LEFT JOIN TO table2 but it has multiple rows per cid
cid imagename status
1 image1-of-cid1 test1
1 image2-of-cid1 test2
2 image1-of-cid2 test3
2 image2-of-cid2 test4
2 image3-of-cid2 test5
But I only want the Query to return the the 1st row only of the each record fom table 1
Thanks
I agree with John Woo's answer above. You need a subquery of some kind to actually retrieve the first row of table 2. Something like:
SELECT
t1.[id],
t2.*
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t2.cid = (SELECT TOP 1 cid FROM table2 WHERE cid = t1.cid)
you need to create an extra subquery that gets one imagename per cid. try this,
SELECT a.*, b.*
FROM table1 a
LEFT JOIN
(
SELECT cid, MIN(imagename) minImage
FROM table2
GROUP BY cid
) c ON a.cid = c.cid
LEFT JOIN table2 b
ON c.cid = b.cid AND
b.imageName = c.minImage
SQLFiddle Demo
Select
distinct a.cid,a.itemdesc,b.imagename,a.itemprice,b.status
from table1 a,
table2 b
where a.cid=b.cid
Try this:
SELECT a.cid, a.itemdesc, a.itemprice, b.imagename, b.status
FROM table1 a
LEFT OUTER JOIN table2 AS b ON a.cid = b.cid
GROUP BY a.cid, a.itemdesc, a.itemprice;
What would be a syntax of the following query:
Get all columns from Table1 and JOIN Table2 if matching reference (Table1ID) exists, otherwise JOIN Table3.
Simplified DB structure is more or less as below
Table1
ID Type
1 std
Table2
ID Table1ID Title Language
1 1 Test en
Table3
ID Table1ID Title Language Flag
1 1 Other en 1
Also, I now realized that Table3 will have multiple entries that refer to single Table1.id. How to limit it to return only the latest entry (with highest id) for every result?
If you don't want an entire separate set of columns for each join, this may be what you're looking for:
SELECT *
FROM (
SELECT a.ID AS Table1ID, a.Type, b.ID, b.Title, b.Language, NULL AS Flag
FROM Table1 a
JOIN Table2 b ON a.ID = b.Table1ID
UNION ALL
SELECT a.ID, a.Type, c.ID, c.Title, c.Language, c.Flag
FROM Table1 a
LEFT JOIN Table2 b ON a.ID = b.Table1ID
JOIN Table3 c ON a.ID = c.Table1ID
JOIN (
SELECT MAX(id) AS maxid
FROM Table3
GROUP BY Table1ID
) d ON c.ID = d.maxid
WHERE b.ID IS NULL
) a
ORDER BY a.Table1ID
SQLFiddle Demo
this is one way to do it.
select table1.id, table1.type, ifnull(table2.title, table3.title)
from table1
left join table2 on table1.id = table2.table1ID
left join table3 on table1.id = table3.table1ID