delete records based on join result - mysql

I have two tables that are joined by an id.
Table A is where I define the records.
Table B is where I use the definition and add some data.
I am doing some data normalization and I have realized that on table B there are some ID that are no longer defined in table A.
If I run this query:
SELECT B.id_cred, A.id_cre from B LEFT JOIN A ON B.id_cred=A.id_cre
I see those records that are NULL on A.id_cre.
I'd like to DELETE from table B those records where the query returns null on table A?
Something like:
DELETE FROM B WHERE id IN (SELECT B.id from B LEFT JOIN A ON B.id_cred=A.id_cre WHERE a.id IS NULL)
but this query throws an error because table B is target and reference at the same time.
You can't specify target table B for UPDATE in FROM clause
Note that the join query will return 1408 rows so I need to do it in a massive way

Option 1, use NOT EXISTS:
delete from B
where not exists (select 1 from A where A.id_cre = B.id_cred)
Option 2, use a DELETE with JOIN:
delete B
from B
left join A on B.id_cred = A.id_cre
where A.id_cre is null

This should do the trick:
DELETE FROM B
WHERE NOT EXISTS (
SELECT id_cre
FROM A
WHERE B.id_cred=A.id_cre)
Just delete any row from B where the key does not exist in A.
NOTE: "A" and "B" can't be aliases, they must be the actual table names.
Hope this helps!

Why not use id_cre from A table since both have the id.
This statement:
DELETE FROM B WHERE id IN (SELECT B.id from B LEFT JOIN A ON B.id_cred=A.id_cre WHERE a.id IS NULL)
simply says that both a and b (B.id_cred=A.id_cre) are the same.

Related

MySql Join Issue When Join Two Tables

I have some doubt in MySQL joins
I have 2 tables for example TableA,TableB
TableA primary key is Foreign key of Table B
So I'm using inner join to get matched values but TableB have one column for row activate status so all active status is zero means I need to get that record or else I need to skip that record.
My query:.
Select * From TableA a inner join TableB b on a.id=b.aid where b.isActive=0;
The above query was return value if any one value is true
For example any one of is active row true. But I need to check all row is zero if it's all value zero means I need to return that so how I do that..?
Thanks in advance.
Select a.*
From TableA a
where not exists(SELECT 1 FROM TableB b WHERE a.id=b.aid AND b.isActive=1);
You can use your query change the filter as follows:
SELECT * FROM TableA a
JOIN TableB b ON a.id=b.aid
WHERE a.id NOT IN(SELECT aid FROM TableB WHERE isActive=1)

LEFT JOIN with id columns for all joined tables

I have two tables that I am applying a join to. Table A has a foreign key that references rows from Table B. SQL is as follows:
SELECT *
FROM TableA AS a
LEFT JOIN TableB AS b ON a.id = b.tableAId
WHERE a.ownerId = X
I am getting the desired result except for one thing. That is when returning the rows in JSON, only one id column is shown (TableB).
Instead I want to be able to return all id columns in the JSON where duplicate columns would have a number appended to it. For example: id, id1, id2, id3 etc...
You need to specify the columns that you want, explicitly giving them aliases so the names are different. Something like this:
SELECT a.*, b.id as b_id
FROM TableA a LEFT JOIN
TableB b
ON a.id = b.tableAId
WHERE a.ownerId = X;

How to merge records from two tables into third using 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)

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 * from main table including foreign key related table

I have 3 tables.
Table A
a_id, a_name, a_description, b_id
Table B
b_id, b_name, c_id
Table C
c_id, c_name (c_name is unique hence no duplicates)
Table "A" has a foreign key 'b_id' to Table "B". Table "B" has foreign key 'c_id' to Table C
I want all Rows of table "A"(No where clause). Each row has 'b_id' so i also need row detail of that foreign key in Table "B". And row details of 'c_id' too.
How can I implement this in an efficient single query? I was using three separate queries and merging result in php. Code looked complicated. I know there is simpler and efficient way since I have just started MySQL.
I am making API that gets all these data and sends to my app.
Edit:
I am doing "SELECT *" from Table "A"
Then I am iterating the array of rows and running "Select b_name from
Table B where b_id = a.b_id"
then "Select c_name from Table B where c_id = b.c_id"
I am merging array result in the end.
What I need in result is * columns from Table A, 'b_name' from Table B and 'c_name' from Table C.
Here you need to use join
Select A.*,B.b_name as b_name,C.c_name as c_name
from A left join B on A.b_id = B.b_id left join C on B.c_id = C.c_id
Use JOIN, for example:
SELECT A.a_id, B.b_id, C.c_id FROM A JOIN B ON A.b_id = B.b_id JOIN C ON B.c_id = C.c_id
More info: http://www.w3schools.com/sql/sql_join_left.asp