【问题标题】:Mysql display information from 4 different tables as one tableMysql将4个不同表的信息显示为一张表
【发布时间】:2014-08-06 20:48:13
【问题描述】:

如何将 4 个不同表中的信息显示为一张表?我有 4 个包含相关信息的表。这些表包含包、组织子级和系统用户数据。我想查询一个组织订阅了什么类型的包以及在该组织下注册了多少孩子和用户。表中包含的示例数据如下所示。

包表

package_id package_name
12 Basic
21 Pro
33 Premium

组织机构表

org_id org_name package_id
18 Marks of Awesomeness 12
24 John Hopkins Hospital 21
38 Teddy and the Wailers 33
78 Lawrence Movers 12

儿童桌

id_child id_org child_name id_org
14 Mark Walker 18
22 Jane Quinn 24
38 Lily Audrey 24
44 Dona Marie 18

用户表

idu org_id fname lname
87 18 John Doe
92 33 Jane Doe
107 18 Martin Short
112 18 Jason Seguel
127 33 Josh Radnor

我的查询如下图:

SELECT SQL_CALC_FOUND_ROWS `id_org`, `org_name`, `package_name`
        ,COUNT(id_child) AS child_count, COUNT(idu) AS user_count FROM organisations,packages,children,system_users
        WHERE organisations.id_org=children.org_id AND organisations.id_org=system_users.org_id
     AND organisations.org_package_id=packages.id_package

查询的问题是它只显示一个组织,如果它有一个孩子和一个用户 使用其 org_id 列出。我想用它订阅的包名列出所有组织的所有数据, 该特定组织下列出的儿童总数,下列出的用户总数 该特定组织,如果组织没有孩子、用户或两者兼有,则为零。 以下是我想要的结果。

期望的结果

Organisation package Name No of Children Number of Users
Marks of Awesomeness Basic 2 3
John Hopkins Hospital Pro 2 0
Teddy and the Wailers Premium 0 2
Lawrence Movers Basic 0 0

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    这将满足您的需求...您需要将两个不包含所有记录的表连接起来,以便用户和孩子...对这些表进行计数并使用 COALESCE 将其取出以处理空值

    注意:

    您的预期结果不正确...组织表中没有 org_id = 33。 Teddy and the Wailers 的计数不应为 2,而应为 0 - 或者您要将用户中的 org_id 更改为 38 而不是 33。

    查询:

    SELECT 
        o.org_name AS 'Organisation', 
        p.package_name as 'Package Name', 
        COALESCE(t.num_children, 0) AS 'No of Children', 
        COALESCE(t1.num_users, 0) AS 'Number of Users'
    FROM organisation o
    JOIN packages p ON p.package_id = o.package_id
    LEFT JOIN 
    (   SELECT 
            COUNT(*) as num_children, id_org 
        FROM children 
        GROUP BY id_org
    ) as t ON t.id_org = o.org_id 
    LEFT JOIN 
    (   SELECT 
           COUNT(*) as num_users, org_id 
        FROM users 
        GROUP BY org_id
    ) as t1 ON t1.org_id = o.org_id
    

    DEMO

    输出:

    +-----------------------+-----------------+-----------------+------------------+
    | Organisation          | Package Name    | No of Children  | Number of Users  |
    +-----------------------+-----------------+-----------------+------------------+
    | Marks of Awesomeness  | Basic           | 2               | 3                |
    | John Hopkins Hospital | Pro             | 2               | 0                |
    | Teddy and the Wailers | Premium         | 0               | 0                |
    | Lawrence Movers       | Basic           | 0               | 0                |
    +-----------------------+-----------------+-----------------+------------------+
    

    编辑:

    如果您将 users 表中的 id 33 更改为 38 以匹配所需的结果,那么您将得到以下结果:QUERY

    输出:

    +-----------------------+-----------------+-----------------+------------------+
    | Organisation          | Package Name    | No of Children  | Number of Users  |
    +-----------------------+-----------------+-----------------+------------------+
    | Marks of Awesomeness  | Basic           | 2               | 3                |
    | John Hopkins Hospital | Pro             | 2               | 0                |
    | Teddy and the Wailers | Premium         | 0               | 2                |
    | Lawrence Movers       | Basic           | 0               | 0                |
    +-----------------------+-----------------+-----------------+------------------+
    

    【讨论】:

      【解决方案2】:

      代替您现在使用的隐式 INNER JOIN,尝试使用 LEFT JOINs 和 COALESCE 函数来处理 NULL 值,如下所示:

      SELECT 
          SQL_CALC_FOUND_ROWS `id_org`, 
          `org_name`, 
          `package_name`,
          COALESCE(COUNT(id_child), 0) AS child_count, 
          COALESCE(COUNT(idu), 0) AS user_count 
      FROM organisations
      INNER JOIN packages ON organisations.org_package_id=packages.id_package
      LEFT JOIN children ON organisations.id_org=children.org_id
      LEFT JOIN system_users ON organisations.id_org=system_users.org_id
      GROUP BY SQL_CALC_FOUND_ROWS, `org_name`, `package_name`;
      

      【讨论】:

        【解决方案3】:

        您需要使用连接:

        select org.org_name, pack.package_name, count(child.id_child) as NoOfChildren,     count(user.idu) as NoOfUsers from Organisation as org
        join Packages as pack
        on pack.package_id = org.package_id
        left outer join Children as child on child.id_org = org.org_id
        left outer join Users as user on user.org_id = org.org_id
        group by org.org_name, pack.package_name
        

        还有更新的小提琴: http://sqlfiddle.com/#!2/cfe16/14/0

        虽然仍然不完全正确,计数已关闭,但似乎已经做出了更好的答案。

        【讨论】:

        • 这在某些级别上是不正确的。1 COUNT(child.*) 是无效代码。需要为 COUNT(child.id_child).. 与 COUNT(user.*) 相同。 2 您需要为用户和孩子提供左连接,因此不会有任何过滤。 3 您在错误信息上加入用户... users.user_id 不存在... 它必须是user.org_id = org.org_id ----- 这是 sql fiddle 玩它和你可以使您的查询正常工作。 sqlfiddle.com/#!2/cfe16/10 :)
        • 谢谢,这个小提琴帮了大忙。 ;) 固定查询:选择 org.org_name, pack.package_name, count(child.id_child) as NoOfChildren, count(user.idu) as NoOfUsers from Organization as org join Packages as pack on pack.package_id = org.package_id left outer join作为 child.id_org 上的孩子的孩子 = org.org_id left outer join 用户作为 user.org_id = org.org_id 上的用户 group by org.org_name, pack.package_name
        • 很高兴它有帮助:)
        猜你喜欢
        • 1970-01-01
        • 2014-10-14
        • 2016-10-03
        • 1970-01-01
        • 2013-04-18
        • 2015-06-05
        • 2019-03-31
        • 2012-12-08
        • 1970-01-01
        相关资源
        最近更新 更多