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
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)
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
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 4 different tables that I want to join. The tables are structured with columns as follows:
TableA - aID | nameA | dID
TableB - bID | nameB | cID | aID
TableC - cID | nameC | date
TableD - dID | nameD
Starting with Table A, I understand how to JOIN tables a and c using b, since b has the Primary Keys for those tables. I want to be able to join table TableD on TableA as well. Below is my SQL statement that first joins tables A and B, then joins that to C:
SELECT TableA.*, TableB.*, TableC.* FROM (TableB INNER JOIN TableA
ON TableB.aID= TableA.aID)
INNER JOIN TableC ON(TableB.cID= Tablec.cID)
WHERE (DATE(TableC.date)=date(now()))
When I attempt to add another join, to include D, I get an error that 'TableD' is unknown:
SELECT TableA.*, TableB.*, TableC.*, TableD.* FROM (TableB INNER JOIN TableA
ON TableB.aID= TableA.aID)
INNER JOIN TableC ON(TableB.cID= Tablec.cID)
INNER JOIN TableA ta ON(ta.dID= TableD.dID)
WHERE (DATE(TableC.date)=date(now()))
You want something more like this:
SELECT TableA.*, TableB.*, TableC.*, TableD.*
FROM TableA
JOIN TableB
ON TableB.aID = TableA.aID
JOIN TableC
ON TableC.cID = TableB.cID
JOIN TableD
ON TableD.dID = TableA.dID
WHERE DATE(TableC.date)=date(now())
In your example, you are not actually including TableD. All you have to do is perform another join just like you have done before.
A note: you will notice that I removed many of your parentheses, as they really are not necessary in most of the cases you had them, and only add confusion when trying to read the code. Proper nesting is the best way to make your code readable and separated out.
SELECT
a.nameA, /* TableA.nameA */
d.nameD /* TableD.nameD */
FROM TableA a
INNER JOIN TableB b on b.aID = a.aID
INNER JOIN TableC c on c.cID = b.cID
INNER JOIN TableD d on d.dID = a.dID
WHERE DATE(c.`date`) = CURDATE()
You have not joined TableD, merely selected the TableD FIELD (dID) from one of the tables.
Simple INNER JOIN VIEW code....
CREATE VIEW room_view
AS SELECT a.*,b.*
FROM j4_booking a INNER JOIN j4_scheduling b
on a.room_id = b.room_id;
Apologies if the title is ambiguous, but I could not figure out a good way to title this problem.
In my database, I have a table J that joins tables A and B. That is to say, J has columns a_id, and b_id that hold the id of entries in A and B respectively. B also has a 'code' column in it; for the sake of example, let's say there are three entries with codes of 'CC', 'DD', and 'EE'.
Now, I want to write a query that lists how many A's have each type of code in B (how many A's have 'CC', how many have 'DD', and how many have 'EE').
I write that query as follows, and get the following output (fabricated data, of course -- sorted by alphabetical code order):
SELECT b.CODE as code, COUNT(*) AS COUNT FROM a, b, j
WHERE j.a_id = a.id AND j.b_id = b.id
GROUP BY b.CODE ORDER BY b.CODE
code | count
==============
CC | 5
DD | 10
EE | 2
The problem occurs when I add in a new record to B, say with code 'FF'. Now at this point, I have no entries in J that point to code 'FF'. So in the output, I want to include 'FF', but show that the count is 0 (no A's are joined to 'FF').
code | count
==============
CC | 5
DD | 10
EE | 2
FF | 0
However, with my current query, it doesn't do this and in fact leaves out all codes where the resulting count is 0.
Can any query masters out there help me to alter my query to include the counts for all codes, whether they are 0 or not? It would be greatly appreciated.
Ian
You'll need to use a LEFT JOIN here to do this. The LEFT JOIN will give you all rows from table b, whether or not they have matching rows in table j.
SELECT b.CODE as code, COUNT(a.id) AS COUNT
FROM b
LEFT JOIN j
INNER JOIN a
ON j.a_id = a.id
ON j.b_id = b.id
GROUP BY b.CODE
ORDER BY b.CODE
You need to use a LEFT JOIN:
SELECT b.CODE as code, COUNT(a.id) AS a_count
FROM b LEFT JOIN (j JOIN a ON j.a_id = a.id) ON j.b_id = b.id
GROUP BY b.CODE ASC