Mysql将来自4个不同表的信息显示为一个表

时间:2014-08-06 20:48:14

标签: php mysql

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

Packages Table
|-------------------------------|
| package_id    | package_name  |
--------------------------------|
| 12            | Basic         |
| 21            | Pro           |
| 33            | Premium       |
---------------------------------

Organisations Table
|-------------------------------------------------------|
| 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            |
|--------------------------------------------------------

Children's Table
|------------------------------------------------|
| id_child      | id_org child_name     | id_org |
|------------------------------------------------|
| 14            | Mark Walker           | 18     |
| 22            | Jane Quinn            | 24     |
| 38            | Lily Audrey           | 24     |
| 44            | Dona Marie            | 18     |
|-------------------------------------------------

Users Table
|------------------------------------------------|
|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                  |
--------------------------------------------------------------------------------------

3 个答案:

答案 0 :(得分:2)

这将做你想要的...你需要加入两个没有所有记录的表,所以用户和孩子......做了一些计数并用COALESCE把它拉出来处理空值

注意:

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

QUERY:

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                |
+-----------------------+-----------------+-----------------+------------------+

答案 1 :(得分:1)

使用LEFT JOINCOALESCE函数来处理NULL值,而不是现在使用的隐式INNER JOIN,如下所示:

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`;

答案 2 :(得分:0)

您需要使用联接:

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

但仍然不完全正确,计数已关闭。不得不上床睡觉,以后会再看一遍,但似乎已经有了更好的答案。