How to merge records from two tables into third using MYSQL - mysql

I have 3 tables A, B, C
Schema of all 3 tables is same as mentioned below:
1st A table:
cpid ,name, place
2nd B table:
connectorid,dob
3rd C table:
ccpid cconnectorid
Now both tables A and B have many records.
Now some of the records in A and B are with same id.
Now I want to merge the records from A and B into Table C.
Merge logic is as follows
1)If records with cpid = connectorid ,insert into table c.
2)C Table ccpid is the foreignkey for A table cpid and cconnectorid is the foreignkey B table connectorid.
3)Using select query.

You can use select insert with a n inner join
insert into table_c
select a.cpid, b.connectorid, a.place
from table_b as b
inner join table_a as a on a.id = b.id

You can try this solution for your query:
INSERT INTO `C`(`ccpid`, `cconnectorid`, `ccity`)
SELECT ta.`cpid`, ta.`cconnectorid`, tb.`place`
FROM `A` as ta
INNER JOIN `B` tb ON ta.`cpid` = tb.`cconnectorid`

You just need join data from both tables? This is simple JOIN function.
SELECT *
FROM Table_A
INNER JOIN Table_B
ON Table_A.cpid =Table_B.connectorid;
You can insert this select to your Table_C.
Here is INNER JOIN, but I think you should take a look to JOINs, here are examples and you can read more about other JOINs.
INNER JOIN: Returns all rows when there is at least one match in BOTH
tables LEFT JOIN: Return all rows from the left table, and the matched
rows from the right table RIGHT JOIN: Return all rows from the right
table, and the matched rows from the left table FULL JOIN: Return all
rows when there is a match in ONE of the tables

use following query replace with your table names
INSERT INTO CTABLE(ccpid,cconnectorid,ccity)
(SELECT A.cpid ,B.connectorid, A.place FROM
TABLEA A INNER JOIN TABLEB B ON A.cpid = B.connectorid)

Related

How to join 3 tables where each has the key to the next in line

Imagine the following scenario:
There are 3 tables A, B and C.
Table A has no knowledge of either table B and table C.
Table B has a foreign key to table A.
Table C has foreign key to table B.
In table B as well as in table C there can be multiple items sharing the same foreign key value.
As you can see, the items from C are indirectly referenced to A through B.
What I want is to get all entries from A that are referenced in C but without any information from B or C in my result tables and without duplicates.
Is this even possible?
I have tried this like so but have no idea if it is correct:
select tableA.*
from tableA,
(select distinct tableB.AId as Aid
from tableB left join tableC on tableC.BId = tableB.id
group by tableB.id)
as temp
where tableA.id = temp.Aid
I am not sure if I understand it correctly, but you can try this one:
SELECT DISTINCT `A`.`id`, `A`.`value1`, `A`.`value2` FROM `A`
INNER JOIN `B` ON `B`.`id-a` = `A`.`id`
INNER JOIN `C` ON `C`.`id-b` = `B`.`id`
It returns all values from table A if there is a key on Table C which is linked to Table B with corresponding foreign key on table A
An alternative approach to Masoud's good response would be to use an exists though a correlated subquery.
The below subquery joins B to C in a correlated fashion (notice the B.IDA to A.ID and A is outside the subquery).
If we assume good database design, then A will not have duplicate records, thus we can omit a distinct here since we are not joining A to the other tables. Instead we are simply checking for the existence of an "A" record in the B table which must have a record in the C table due to the inner join. This has two advantages for performance
It doesn't have to join all the records together which would then
necessitate a distinct; thus you don't have the performance hit on
the distinct.
It can early escape. once a key value of A is found in the
subquery (B to C join) , it can stop looking and thus don't have to join all of B to all of A.
We select "1" in the subquery as we don't care what we select as the value will not be used anywhere. We're just using the coloration of A to (B JOIN C) to determine what in A to display.
SELECT A.*
FROM A
WHERE EXISTS( SELECT 1
FROM C
INNER JOIN B
on C.IDB = B.ID)
AND B.IDA = A.ID)
Taking what you tried and reviewing it:
select tableA.*
from tableA,
(select distinct tableB.AId as Aid
from tableB left join tableC on tableC.BId = tableB.id
group by tableB.id)
as temp
where tableA.id = temp.Aid
Starting with the "FROM"
You have tableA, (subquery) temp. This is a CROSS JOIN meaning all records from A will be joined to ALL records of (B JOIN C) so if you have 1000 records in A and 1000 records in the temp result then you'd be telling the database engine to generate 1000*1000 records in your result set; which then gets filtered to only include records matching in temp and A. The engine may be smart enough to avoid the cross join and optimize the query, but I find it confusing to maintain. So I would rewrite as
SELECT tableA.*
FROM tableA
INNER JOIN (SELECT distinct tableB.AId as Aid
FROM tableB left join tableC on tableC.BId = tableB.id
GROUP BY tableB.id) as temp
ON tableA.id = temp.Aid
Looking at the subquery (temp)
We don't need a group by as we are not aggregating. The distinct does bring us down to 1 record but at a cost to execution time.
So I would re-write as this:
SELECT tableA.*
FROM tableA
INNER JOIN (SELECT distinct tableB.AId as Aid
FROM tableB
LEFT JOIN tableC
on tableC.BId = tableB.id) as temp
ON tableA.id = temp.Aid
Then looking at the whole, if we change the outer query join to temp and make it an exists... using coloration we don't have the performance hit of the join, nor the distinct. and I'd switch the left join to an inner as we only want records in C and B so we'd have null in B if we left it as a "LEFT JOIN" which serve no purpose for us.
This gets me to the answer I initially provided.
SELECT tableA.*
FROM tableA
WHERE EXISTS (SELECT 1
FROM tableB
INNER JOIN tableC
on tableC.BId = tableB.id
AND tableB.AID = A.ID) as temp

Is it possible to include ALL fields from joined table EXCEPT joined one?

Very often join fields have the same name in joined tables. If just join
SELECT a.*, b.* FROM a INNER JOIN b ON a.id=b.id
it will produce id field twice.
Is it possible to include ALL fields from joined table EXCEPT joined one?
UPDATE
I am using MySQL but standard way is also interesting to me!
UPDATE 2
Regarding USING syntax, how to use it with multiple joins?
SELECT * FROM
a INNER JOIN b USING (b_id)
INNER JOIN c USING (c_id)
swears table b doesn't contain c_id field, which is true, since it is inside a.
Normally I would write
SELECT * FROM
a INNER JOIN b ON a.b_id = b.b_id
INNER JOIN c ON a.c_id = c.c_id
In standard SQL this is achieved through USING
select *
from a
join b using (id);
This will return the id column only once.

Oracle Select Query based on Column value

I have two tables lets say
Table A
columns id , name address
Table B
columns id , age, import_date
The Table B id is a reference key of Table A.
Now I want to return results from A & B but if the record is not in B I still want to see the record so for this I use left outer join
Select * from A a left join B b
on a.id = b.id
Now even I don't have record in B I still get the record.
Table B may contain duplicate ids but unique import_date.
Now I want to results in a way that if there is duplicate id in table B then I want to get the records only where import_date is as of today.
I still want to get the records for ids which are not there but if the ID is there in table B then I want to apply above condition.
I hope someone can help me with this.
Sample data
Table A
01|John|London
02|Matt|Glasgow
03|Rodger|Paris
Table B
02|22|31-AUG-2015
02|21|30-AUG-2015
02|23|29-AUG-2015
The query will return
01|John|London|null|null|null
02|Matt|Glasgow|22|31-Aug-2015
03|Rodger|Paris|null|null
You almost got the solution. Just add one more condition like below
Select a.id,a.name,a.address,b.age,b.import_date
from tablea a left join tableb b
on a.id=b.id and b.import_date=trunc(sysdate)
order by a.id;---This line optional
Check the DEMO HERE
SELECT *
FROM Table_A t1 LEFT OUTER JOIN Table_B t2 ON t1.id=t2.id UNION
SELECT *
FROM Table_A t1 LEFT OUTER JOIN Table_B t2 ON t1.id=t2.id
GROUP BY t2.import_date
HAVING t2.import_date=CURDATE();

Select records from one table where a column value exists in another table

I have 2 MySQL tables A and B.
I would like to select only the records from B where a certain value exists in A.
Example:
A has columns: aID, Name
B has columns: bID, aID, Name
I just want the records from B for which aID exists in A.
Many thanks.
You need to do either INNER JOIN - records that exists in both tables, or use LEFT join, to show records that exists in A and matching IDs exists in B
A good reference:
You need to make a join, and if you don't want to retrieve anything from table b, just return values from table a.
This should work
select b.* from b join a on b.aID=a.aID
Below query will also work and will be effective
SELECT * FROM B
WHERE B.aID IN (SELECT DISTINCT aID FROM A)
You just need a simple inner join between tables A and B. Since they are related on the aID column, you can use that to join them together:
SELECT b.*
FROM tableB b
JOIN tableA a ON a.aID = b.aID;
This will only select rows in which the aID value from tableB exists in tableA. If there is no connection, the rows can't be included in the join.
While I recommend using a join, you can also replace it with a subquery, like this:
SELECT *
FROM tableB
WHERE aID NOT IN (SELECT aID FROM tableA)
You can use join like this.
Select b.col1,b.col2... From tableB b inner join table tableA a on b.field = a.field
Have you tried using a LEFT JOIN?
SELECT b.* FROM tableB b LEFT JOIN tableA a ON b.aID = a.aID

SQL JOINING, Which is the best join

I'm trying to collate data from three tables.
tableA, tableB and tableC. Table A is my main table containing the most data I want to pull.
Table A joins to Table B via a.id and b.new_id. However, Table C does not have any association to Table A and joins only through Table B: b.board_id and c.board_id.
Which is the best way to join these tables so that the variables will represent table A?
I can connect tables A and B like this:
SELECT * FROM tableA a LEFT JOIN tableB b ON a.id = b.new_id and the variables are fine. But when I try to add TableC the variables shown are that of TableC, not TableA.
Some of the tables contain identical column names. How would I join all three?
It must be like this:
SELECT * FROM tableA a LEFT JOIN tableB b ON a.id = b.new_id join tableC c on c.board_id=b.board_id
You query should look like this:
SELECT a.col1 as a_col1, a.col2 as a_col2, . . .
FROM tableA a LEFT JOIN
tableB b
ON a.id = b.new_id left join
tablec c
on b.board_id = c.board_id;
You don't have to create a separate name for all columns, you only need to do it for the ones with duplicates.