Find number of joins by a reference table - mysql

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

Related

Connecting two mySQL tables and and summarising with unique values

I've got two mySQL tables, Table A and B. I need to get an output like in Table 3.
Below mentioned is the code I tried with Full Join and does not give me the intended result. Much appreciate your help..
SELECT DISTINCT(Table_A.Code) as 'Code', SUM(Table_A.Qty_On_Hand) as 'On Hand Qty', SUM(Table_B.Counted_Qty) as 'Counted Qty'
FULL JOIN Table_B ON Table_A.Code = Table_B.Code
FROM Table_A
Table A
Code
On Hand Qty
A
20
B
10
B
20
B
50
C
60
Table B
Code
Counted Qty
A
10
B
0
C
30
B
0
C
10
Out put required:
Code
On Hand Qty
Counted Qty
A
20
10
B
80
0
C
60
40
You need to use GROUP BY Table_A.Code, not DISTINCT.
SELECT a.Code, SUM(a.Qty_On_Hand) AS `On Hand Qty`, b.`Counted Qty`
FROM Table_A as a
JOIN (
SELECT Code, SUM(Counted_Qty) AS `Counted Qty`
FROM Table_B
GROUP BY Code
) AS b ON a.Code = b.Code
GROUP BY a.Code
You need to do one of the SUMs in a subquery, otherwise you'll multiply its sums by the number of rows in the other table. See Join tables with SUM issue in MYSQL.

select record only if specific related values are provided in mysql

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');

Mysql SELECT eliminate rows duplicate values in one column (joining 2 tables)

This is a different question because I have joined 2 tables. The solutions for the duplicate question indicated does not work for me.
This is the query:
SELECT a.id, a.userName, IF(o.userId = 1, 'C', IF(i.userId = 1,'I','N')) AS relation
FROM tbl_users AS a
LEFT JOIN tbl_contacts AS o ON a.id = o.contactId
LEFT JOIN tbl_invites AS i on a.id = i.invitedId
ORDER BY relation
This returns the output as follows:
id username relation
1 ray C
2 john I
1 ray N
I need to remove the third row from the select query by checking if possible that id is duplicate. I tried adding distinct(a.id) but it doesn't work. How do I do this?

MySQL join a different table based on field value

I have a table containing the last comments posted on the website, and I'd like to join a different table depending on the comment type.
Comments Table is similar to this structure:
id | type | ressource_id |
---+------+--------------+
1 | 1 | 10 |
2 | 3 | 7 |
What I'd like to do is to join the "News" table if type type = 1 (on news.id = comments.ressource_id), "tutorial" table if type type = 3, etc.
How can I do this please? I've tried different queries using CASE and UNION, but never got the expected results.
Thanks.
Try using left outer join and a on clause matching on the type:
select coalesce(n.id, t.id) id
, c.type
, c.resource_id
from comments c
left
outer
join news n
on n.id = comments.resource_id
and c.type = 1
left
outer
join tutorial t
on t.id = comments.resource_id
and c.type = 3
You can do this with unioned queries assuming that you can coerce partial queries into producing a similar schema, along the lines of:
select n.id as id, c.something as something
from news n, comments c
where n.type = 1
and n.id = c.resource_id
union all
select n.id as id, t.something as something
from news n, tutorial t
where n.type = 3
and n.id = t.resource_id
In other words, the first query simply joins news and comments for rows where news.type indicates a comment, and the second query joins news and tutorials for rows where news.type indicates a tutorial.
Then the union combined the two into a single record set.
I'd steer clear of case in this situation (and many others) since it almost always invariably requires per-row modification of the data, which rarely scales wee. Running two queries and combining the results is usually more efficient.

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