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)
Related
I have Table Having 2 columns
Cust1 Cust2
A B
C A
A C
C D
B A
D C
We need to remove these duplicates and retain only one combination
So Output could be either
Cust1 Cust2
A B
A C
C D
OR
Cust1 Cust 2
B A
C A
D C
Selecting unique combinations:
SELECT DISTINCT LEAST(Cust1, Cust2) Cust1,
GREATEST(Cust1, Cust2) Cust2
FROM source_table
Removing "duplicates" (assuming that there is no full duplicated rows, by both values and order - they won't be removed):
DELETE t1.*
FROM source_table t1
JOIN source_table t2 ON (t1.Cust1, t1.Cust2) = (t2.Cust2, t2.Cust1)
WHERE t1.Cust1 > t1.Cust2
Recommendation - create unique index by (LEAST(Cust1, Cust2), GREATEST(Cust1, Cust2)), it will forbid duplicates insertion.
If you have pairs in both directions, then the simplest method is:
select t.*
from t
where cust1 < cust2;
If you want to modify the table, then:
delete t from t
where cust1 > cust2;
Both of these can be modified to handle singletons, but there are no examples in your question.
I 3 have tables, 2(A and B) of them have many to many relationship, they connected through pivot C table. tables desc:
A(id, name)
B(id, is_required)
C(a_id, b_id)
I want to select records from A table, which related record ids from B table are in provided input and fit some condition. for example:
lest say I have list of integers(ids) [1,2,3,4,8,12] and also one record from A has 5 related records from B, example:
A
id name
1 test
-------------
B
id is_required
1 true
2 true
3 false
10 false
16 false
I need to select records from table A join related records from table B, and check - if all required(is_required = true) record ids from B exists in my list ([1,2,3,4,8,12]) then we select this record, otherwise not. so the first example should be selected, because all required records from B (1 and 2) exists in list. for example this:
A
id name
2 test2
-------------
B
id is_required
1 true
2 true
5 true
6 false
should not be selected, because required record with id 5 not provided in list. how can I implement this in mysql? query example:
SELECT A.id, A.name FROM A, B, C
WHERE A.id = C.a_id
AND C.b_id = B.id
as you see, for now its only joins related data, I really don't know how should I implement this. can you please help me?
I believe that you need NOT EXISTS
select A.*
from A
where not exists(
select 1
from C
join B on C.b_id = B.id and
A.id = C.a_id and
is_required = 'false'
)
You can use group by and having:
select c.a_id
from c join
b
on c.b_id = b.id and b.is_required = 'true'
group by c.a_id
having count(*) = (select count(*) from b where b.is_required = 'true');
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)
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
I am planning to create a website similar to IMDB.com. To reduce execution time I am using the following structure. Is it okay for faster working?
Table - 1
Id Movie_name description
1 name one some description
2 name two some description
3 name three some description
Table 2
id actorname
1 name 1
2 name 2
3 name 3
4 name 4
Table 3
id movieid actorid
1 1 1
2 1 2
3 1 3
4 1 9
5 2 6
6 2 5
7 2 8
8 2 1
When I want to list actors in a movie program will retrieve actors ids from table 3 and find respective names from table 2 (using single query). When I want to list the movies of a actor it will retrieve movie ids from table 3 and find respective names from first table. Will it work properly? Any other ideas?
This will give all actors in a specified movie,
SELECT c.ID, c.actorName
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE a.ID = 1
This one will give all movies for a specified actor
SELECT a.*
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID = 1
SQLFiddle Demo (both queries)
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
UPDATE 1
This is called Relational Division
SELECT a.ID, a.Movie_Name
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID IN (1, 2, 3)
GROUP BY a.ID, a.Movie_Name
HAVING COUNT(DISTINCT c.ID) = 3
SQL of Relational Division
I suggest that you modify table3 by taking away the id field. Use the movieid and actorid together as your primary key. You might want to add other fields to this table such as name of character and order of appearance as suggested in the comment by Jermaine Xu.