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)
Related
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)
so i have two tables.
users
users_id | firstname | lastname
10001 | mike | lapiz
10002 | tom | jerry
profile
profile_id | department | specialization
10001 | Health Dept | Heart
10002 | Brain Dept | Brain
maybe you're curious why i separate the name of the user and the profile.. i have my on reasons for that.. what i wanted to do is to select my all fields from profile then join the users table
what i want to be the result is
users_id | firstname | lastname | profile_id | department |specialization
10001 | mike | lapiz | 1001 | health dept | heart
this is my query..
$sql = SELECT a.profile_id,a.department,a.specialization FROM `tbl_profile` AS a LEFT JOIN (SELECT users_id,firstname,lastname FROM `tbl_users`) AS b ON a.profile_id = b.users_id
what happen is it only display the profile table.. it is not displaying the other table.. and when i tried to
LEFT JOIN (SELECT b.users_id,b.firstname,b.lastname FROM `tbl_users`) AS b
it give me an error unknown column b.users_id
You misunderstand how a join works.
FROM tbl_profile JOIN tbl_users ON ...
joins the two tables, i.e. combines records on the given condition in ON.
FROM tbl_profile JOIN (SELECT * FROM tbl_users)
does exactly the same. It makes no difference if you join a table directly or join the records of the table, because this means exactly the same.
FROM tbl_profile JOIN (SELECT users_id, firstname, lastname FROM tbl_users)
again does the very same thing. Only that you restrict the columns you can use in the query to the three stated columns. So if there existed more columns in the table, you could not use them in the query's select or where or order by clause anymore.
So a join means just combining records. Which columns you want to show, you put in the select clause:
SELECT * FROM tbl_profile JOIN tbl_users ON ...
selects all columns from both tables.
SELECT p.department FROM tbl_profile p JOIN tbl_users u ON ...
selects only the department.
You want:
SELECT * FROM tbl_users u JOIN tbl_profile p ON p.profile_id = u.user_id
A LEFT JOIN by the way is an outer join where you keep the records from the left table in your results even when there is no match in the right table. In your query you said that you wanted to show profile records too that have no match in the users table, which was certainly not intended.
You should use inner join not nested inner join
$sql = SELECT a.profile_id,a.department,a.specialization,b.users_id,b.firstname,
b.lastname FROM tbl_profile AS a inner join tbl_users b
ON a.profile_id = b.users_id
As you want to list all the columns in both the tables with LEFT OUTER JOIN, the following query will serve your purpose:
SELECT * FROM users LEFT OUTER JOIN profile on users.users_id = profile.profile_id
You can use the alias as well if you want as following:
SELECT * FROM users u LEFT OUTER JOIN profile p on u.users_id = p.profile_id
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
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
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)