【问题标题】:Select total of childrens in multiple tables in one query with mysql使用 mysql 在一个查询中选择多个表中的子项总数
【发布时间】:2012-09-29 01:21:50
【问题描述】:

我整个下午都在试图处理一个查询(或两个或三个)以获取三个表的所有子项的计数。看看我的设计:

用户表

id_user | name
1 | foo
2 | bar

赢了桌

id_won | user
1 | 1
2 | 1
3 | 2

绘制表格

id_draw | user
1 | 1
2 | 2
3 | 2

丢表

id_lose | user
1 | 1
2 | 1
3 | 1

我正在尝试得到这样的东西:

name | wons | draws | loses
foo | 2 | 1 | 3
bar | 1 | 2 | 0

这是我的尝试:

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;

【问题讨论】:

    标签: mysql sql count multiple-tables


    【解决方案1】:

    您可以在子查询中计算它们的总值并将它们加入表users。我添加了COALESCE 以显示zero 而不是null,以防user 出现在其他表上。

    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

    【讨论】:

    • 我建议计算 id 而不是使用 *.原因是如果表有更多字段(它可能有),您不需要从表中提取其余信息,并且您的查询更“可索引”。
    【解决方案2】:
    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
    

    这只是任务所需的工作量。

    【讨论】:

    • 非常感谢@Francisco Soto,您的问题正是我想要的:)
    【解决方案3】:

    最干净的 SQL 是:

    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
    

    http://sqlfiddle.com/#!2/91b61/10

    【讨论】:

      【解决方案4】:

      我会建议一种替代方法,这可能对您的项目来说有点过头了,但如果您要大量生成所需的结果,请牢记性能。

      创建一个汇总表(类似于您想要的输出)。您可以在那里清空为每个用户创建的 shell 记录。

      在赢、平和输表中添加触发器,简单地更新汇总表中的数据。

      这是一种方法。下一种方法是,如果您想要的结果不是关键任务(即不必是最新的东西),那么考虑添加一个计划的事件(每 10 或 20 分钟运行一次,运行上面提供的查询(我已经给出 +1 票)并使用它来更新汇总表。

      祝你好运!

      【讨论】:

      • 好吧,我同意你的看法,但是当前数据库不能更改。做一个总结触发器会很棒呵呵:D
      猜你喜欢
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多