问题
All my afternoon was consumed trying to deal with a query (or two or three) in order to get the count of all childs of three tables. Take a look to my design:
user table
id_user | name
1 | foo
2 | bar
wons table
id_won | user
1 | 1
2 | 1
3 | 2
draws table
id_draw | user
1 | 1
2 | 2
3 | 2
loses table
id_lose | user
1 | 1
2 | 1
3 | 1
I'm trying to get something like this:
name | wons | draws | loses
foo | 2 | 1 | 3
bar | 1 | 2 | 0
This is my try:
select
u.name, w.total_w, d.total_d, l.total_l
from
user u
LEFT JOIN
(select count(user) as total_w, user from wons group by user) as w
ON w.user = u.id_user
LEFT JOIN
(select count(user) as total_d, user from draws group by user) as d
ON d.user = w.user
LEFT JOIN
(select count(user) as total_l, user from loses group by user) as l
ON d.user= .user
group by u.id_user;
回答1:
select u.name, w.uw as wins, l.ul as loses, d.ud as draws from user
left join (select user, COUNT(id_won) uw from wons group by user) w on w.user = u.user_id
left join (select user, COUNT(id_lose) ul from loses group by user) l on l.user = u.user_id
left join (select user, COUNT(id_draw) ud from draws group by user) d on d.user = u.user_id
This one would just the needed amount of work for the task.
回答2:
You can calculated their total values in a subquery and joined them on table users
. I added COALESCE
to show zero
instead of null
in the case the user
is not present on the other tables.
SELECT a.id_user,
COALESCE(b.totalWon,0) Wons,
COALESCE(d.totalLoses,0) Loses,
COALESCE(c.totalDraws,0) Draws
FROM users a
LEFT JOIN
(
SELECT `user`, COUNT(id_won) totalWon
FROM wons
GROUP BY `user`
) b ON a.id_user = b.`user`
LEFT JOIN
(
SELECT `user`, COUNT(id_draw) totalDraws
FROM draws
GROUP BY `user`
) c ON a.id_user = c.`user`
LEFT JOIN
(
SELECT `user`, COUNT(id_lose) totalLoses
FROM loses
GROUP BY `user`
) d ON a.id_user = d.`user`
SQLFiddle Demo
回答3:
The cleanest SQL is:
SELECT
u.name,
w.wins,
d.draws,
l.loses
FROM
user u
LEFT JOIN
(SELECT user,COUNT(*) wins FROM wons GROUP BY user) w ON w.user = u.id_user
LEFT JOIN
(SELECT user,COUNT(*) draws FROM draws GROUP BY user) d ON d.user = u.id_user
LEFT JOIN
(SELECT user,COUNT(*) loses FROM loses GROUP BY user) l ON l.user = u.id_user
See http://sqlfiddle.com/#!2/91b61/10
回答4:
I'll suggest an alternative approach which might be an overkill for your project but keeps performance in mind if you are going to generate the desired result a lot.
Create a summary table (similar to your desired output). You can empty shell record created for each user there.
Add triggers in won, draw and losses table that simply updated the data in summary table.
That's one approach. Next approach is if your desired result isn't mission critical (i.e. does not have to be an up to date thing) then consider adding a scheduled events (that run every 10 or 20 min that run the query provided above (which I've given +1 votes) and use that to update the summary table.
Best of luck!
来源:https://stackoverflow.com/questions/12649119/select-total-of-childrens-in-multiple-tables-in-one-query-with-mysql