is any record connected to anather - mysql

TABLE A
id=1
+file_id=100
|
| TABLE B
|id=1
+file_id=100
|
|TABLE FILES
>id=100
file_name = picture.jpg
file_size = 99999
file_id of TABLE A and TABLE B are in connection width TABLE FILES id.
I would like to check if any of the two table records are pointed to the file with let sey id=100. If not the file would be deleted.
How can I do this?

You can get a list of ids that are not linked to by any of the two tables with this query:
SELECT f.id AS id FROM files f
LEFT JOIN a ON f.id = a.file_id
LEFT JOIN b ON f.id = b.file_id
WHERE a.id IS NULL AND b.id IS NULL
The idea is that you perform a left outer join to the A and B tables starting from table FILES; records in FILES that do not have a corresponding entry on the other tables (as specified by the JOIN condition) will have NULL values for all columns of these tables. Therefore, if a row has NULL for both a.id and b.id it means that there is no corresponding row in either of the A, B tables for the specific file.

Delete the results of the query:
SELECT filename
FROM files f
WHERE (
NOT EXISTS (SELECT * FROM A WHERE file_id= f.id)
AND NOT EXISTS (SELECT * FROM B WHERE file_id = f.id)
)
This (ideally) gets the files which are not referenced in either A or B

Another way to do it:
DELETE F
FROM files AS F
LEFT JOIN tablea AS A ON F.`id` = A.`file_id`
LEFT JOIN tableb AS B ON F.`id` = B.`file_id`
WHERE ISNULL(A.id) AND ISNULL(B.id);
(after posting this I've seen thats the same approach already used by Jon)

Related

MySQL join table based on condition

I have a requirement where If a certain conditions matches then I need to apply JOIN otherwise, I don't need to apply it.
for example
A,B and C are tables
so I need to join B and C if the B.id not in (select entityId from A) otherwise there will be no join.
also here A and C don't have common values.
Table A
id entityId name
1 xyz abc
2 bcd z
3 edc x
Table B
id entityId shopRegID
1 bcd z
Table C
id entityId newEntityID ShopNewname
1 xyz xyze abcd
2 e ee sd
now I have condition like this, where I need to get the data from these table ,based on the entityId provided to me.
I need to eliminate all the shops which are not registered(not in table B) but include the shops which are renamed(in table C but not in B)
suppose If I am given ('xyz','bcd','edc')
the output should contains
bcd (because it's in table B)
xyz (because it's in table C)
and these table have very large amount of data(in 100 thousands )
what is the best and performant way to achive this.
You can use left join and coalesce as follows:
select *
from tableA A
left join tableB B on a.entityid = b.entityid
left join tableB C on a.entityid = c.entityid
WHERE coalesce(b.entityid,c.entityid) is not null
It sounds like you want entities from a that are in either of the tables. This suggests exists logic:
select a.*
from a
where exists (select 1 from b where b.entityId = a.entityId) or
exists (select 1 from c where c.entityId = a.entityId)

Best Fit data retrial using left Join in MySQL

Below is something I am trying to achieve.
Data from 3 different files are loaded into a single table in which I need to categorize the data based on the names, and check for the best fit of the data across all rows.
The same name can have a maximum of 3 occurrences inside the table and a minimum of 1.
The data comparison should happen on all 3 rows or 2 rows (If the name did not come from one source) if there are more than one occurrences for a given name. If there is only 1 row for a given name that should be taken as the default value.
This is my attempt.
select
case
when (coalesce(length(A.x_manufacturer),0) > coalesce(length(B.x_manufacturer),0) AND coalesce(length(A.x_manufacturer),0) > coalesce(length(C.x_manufacturer),0)) then A.x_manufacturer
when (coalesce(length(B.x_manufacturer),0) > coalesce(length(A.x_manufacturer),0) AND coalesce(length(B.x_manufacturer),0) > coalesce(length(C.x_manufacturer),0)) then B.x_manufacturer
when (coalesce(length(C.x_manufacturer),0) > coalesce(length(A.x_manufacturer),0) AND coalesce(length(C.x_manufacturer),0) > coalesce(length(B.x_manufacturer),0)) then C.x_manufacturer
else C.x_manufacturer end as Best_Fit_x_manufacturer
from tbl1 A left outer join tbl1 B on
A.name = B.name
left outer join tbl1 C on C.name = B.name
where A.sourceid=1 and B.sourceid=2 and C.sourceid=3 group by
C.name
Sample Data in Table:
Name ManuFacturer source
A AB 1
A ABC 2
A ABCD 3
B BC 1
Expected Output
Name ManuFacturer source
A ABCD 3
B BC 1
As soon as you put a solid condition on an outer joined table, into the WHERE clause, the join reverts to INNER join behavior:
from
tbl1 A
left outer join tbl1 B on A.name = B.name
left outer join tbl1 C on C.name = B.name
where
A.sourceid=1 and
B.sourceid=2 and --wrong; this will cause A outer join B to become an INNER join
C.sourceid=3 --wrong; this will cause B outer join C to become an INNER join
Put your clauses in the ON instead:
from
tbl1 A
left outer join tbl1 B on A.name = B.name AND B.sourceid=2
left outer join tbl1 C on C.name = B.name AND C.sourceid=3
where
A.sourceid=1
The reason why is:
Outer joins generate NULLs in every column if there's no match between rows, hence B.sourceid might well be null in some rows of the result set. Specifying WHERE B.sourceid=2 causes all the rows where sourceid is null, to disappear, because 2 is not equal to null (nothing is equal to null). This means the only rows that you can possibly get out of it is rows where there IS a match.. Which is an inner join

OR on INNER JOIN 3 Tables

I'm having some problems with this query and i don't know where's the error.
SELECT
DISTINCT(A.email)
FROM TABLE A
JOIN TABLE B
ON A.id=B.userid
JOIN TABLE C
ON A.id=C.userid
WHERE C.sfID = 200
OR B.sfID = 200
When I run the query on PHPMyAdmin stays on loading forever.
Edit:
Here are the tables to try to explain
TABLE A
USERID | EMAIL
TABLE B
ID | SID | USERID
TABLE C
ID | SID | USERID
TABLE D (i don't want to use this)
SID | SNAME
So, i need to get the email from TABLE A of the users who have SID 200 on TABLE B or TABLE C
UNTESTED:
I think you're missing join criteria on C which is causing the engine to have to join more records together than it should; or you could join C though B instead of A. This only works because you're using an INNER Join in all cases. If they are outer joins, we couldn't go from A->B->C
This may be faster:
SELECT DISTINCT A.email
FROM TABLE A
JOIN TABLE B
ON A.id=B.userid
JOIN TABLE C
ON A.id=C.userid
AND B.userID = C.USERID
WHERE (C.sfID = 200 OR B.sfID = 200)
A-->B
A-->C
the engine doens't know how to tie B-C so if B and C have multiple records for each value in A, then you're joining a M:M, in effect a cross join.
or it could be written as: thus joining A-->B-->C
SELECT DISTINCT A.email
FROM TABLE A
JOIN TABLE B
ON A.id=B.userid
JOIN TABLE C
ON B.userID = C.userID
WHERE (C.sfID = 200 OR B.sfID = 200)

SQL Statement to retrieve information from multiple tables

I need some help constructing a SQL Statement.
I just have basic knowledge concerning SQL (insert, delete, alter, where, select) but never really had to deal with aggregate functions or joins.
So here is the setup:
TABLE A
cust_id
prod_id
statusCode
...
TABLE B
cust_id
land_id
...
TABLE C
country_id
...
TABLE D
country_id
country_code
TABLE E
product_id
country_code1
What the SQL Statement should output is: All rows where the statusCode from Table A is 1, or 2, or 3 and where the country_code == country_code1.
Where country_code can obtained via Table B,C,D and country_code1 via Table E.
Please do not post answers concerning the database structure itself since i have no rights to change them.
My approach was this but it is clear that it is horribly wrong since I am a SQL beginner:
SELECT * FROM TableA
INNER JOIN TableB ON TableA.cust_id = TableB.cust_id
INNER JOIN TableC ON TableB.landId = TableC.country_id
INNER JOIN TableE ON TableA.prod_id = TableE.product_id
INNER JOIN TableD ON TableE.country_code1 = TableD.country_code
WHERE statusCode IN (1,2,3)
Off the top of my head.
Join the two groups of tables with FK
Join those groups,
Restrict that super set
more to come
SELECT *
FROM (tableA A INNER JOIN tableB B ON A.cust_id=B.cust_id)
INNER JOIN tableE E ON E.product_id=A.prod_id
INNER JOIN (tableC C INNER JOIN tabldeD D ON D.country_id)
ON D.country_code = E.country_code1
WHERE A.statusCode IN(1,2,3)
We don't have to worry about the country code bit because it is in the 'join'.
Off the top of my head (untested, and I'm not 100% sure that this is what your requirement is):
select a.cust_id, a.prod_id, a.statusCode,
b.land_id,
c.country_id,
d.country_code,
e.product_id
from TableA a, TableB b, TableC c, TableD d, TableE e
where a.cust_id = b.cust_id -- basic joins on common fields
and b.land_id = c.country_id
and b.land_id = d.country_id
and d.country_code = e.country_code1
and a.statusCode in (1, 2, 3) -- finally the statuscode selection

dependent query in mysql?

I have three tables like A,B,C and here what my requirement is
in A table having two foreign key from B and C table and
I want if b_id is not null then get data from the B table
else if c_id is not null then get data from the C table.
B and C Tables having the three to four colums. Please see the following structure.
A Table
a_id(pk) | b_id(fk) | C_id(fk)
1 | null | 1
2 | 2 | null
For that above requirement i tried but not achieve my goal. please anybody to do this.
Thanks in advance
If I understand correctly your question you want to do a left join on tables B and C
Select B.*, C.*
From table_A A left join Table_B B on A.B_Id=B.Id
left join Table_C C on A.C_Id = C.Id
Probably you mean to have left joins on table B and C and COALESCE some value (or values? you did not provide any column list or what your desired output is so I assume there is just one content containing column in table B as well as in C)
For selecting from one column in those tables I would do the following
SELECT
COALESCE(B.yourcontentcolumn, C.yourcontentcolumn, <defaultvalueifnull>)
FROM A
LEFT JOIN B ON B.id = A.b_id
LEFT JOIN C ON C.id = A.c_id