【问题标题】:Query inside query returned "as a column"查询内的查询返回“作为列”
【发布时间】:2017-01-17 09:16:58
【问题描述】:

我喜欢在一个表格中列出所有公司以及每个特定公司拥有的管理员数量。

表格:

companies
id
name
...

users
id
company_id
...

groups ('id' = 1 has 'name' = admin)
id
name 

users_groups
id
user_id
group_id

为了列出所有“公司”,我这样写:

SELECT companies.name
FROM companies

为了获得一个特定“公司”(具有给定 id)中“管理员”的数量,我写了这个

SELECT COUNT (users.id) 
FROM users, companies, users_groups WHERE
users.company_id = companies.id AND 
users_groups.user_id = users.id AND
users_groups.group_id = 1

那么我该如何合并这两个问题呢?这失败了:

SELECT 
  companies.name, 
    (
      SELECT COUNT (users.id) 
      FROM users, companies, users_groups WHERE
      users.company_id = companies.id AND 
      users_groups.user_id = users.id AND
      users_groups.group_id = 1
    ) 
  as admins_in_company
FROM users, companies, users_groups

【问题讨论】:

    标签: sql select count mariadb


    【解决方案1】:

    使用显式连接语法和计数(不同...):

    select c.name, count(distinct u.id)
    from companies c
    inner join users u
      on u.company_id = c.id
    inner join users_groups ug
      on ug.user_id = u.id
    where ug.group_id = 1
    group by c.name
    

    适用于所有公司:

    select c.name, count(distinct u.id)
    from companies c
    left join users u
      on u.company_id = c.id
    left join users_groups ug
      on ug.user_id = u.id
      and ug.group_id = 1
    group by c.name
    

    【讨论】:

    • 谢谢!您是否知道如何编写查询,以便返回所有公司(也包括没有管理员的公司)。我试图用“左连接”替换“内连接”,但没有成功。
    • 再次感谢!现在我正在尝试进行过滤,以便只有拥有 users.active = 1 的管理员将被包含在 COUNT 中,并且再次显示所有公司的结果。 grisbukten
    【解决方案2】:
    SELECT c.name, COUNT(DISTINCT u.id) AS num_admins
        FROM groups AS g
        JOIN users_groups AS ug   ON ug.group_id = g.id
        JOIN users AS u           ON u.id = ug.user_id
        JOIN companies AS c       ON c.id = u.company_id
        WHERE g.group_id = 1
          AND g.name = 'admin'
        GROUP BY u.company_id;
    

    目前尚不清楚您需要COUNT(DISTINCT u.id) 还是只需要COUNT(*)

    我按照查看顺序列出了 4 个表格。 (这不是必需的,但可以让用户更容易阅读和思考。)首先是groups,它包含所有的 'filtering(WHERE). Then it moves through the other tables all the way to getting thecompany.name. Then theGROUP BY@987654329 @COUNT(DISTINCT...)` 被应用。

    many:many 模式 (users_groups) 设计技巧:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

    groups -- group_idandgroup.nameare in a 1:1 relationship, yes? If you know that it isgroup_id = 1, you can get rid of the tablegroupscompletely from the query. If not, then be sure to haveINDEX(name)` 在该表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 2010-12-18
      • 2018-09-21
      相关资源
      最近更新 更多