【问题标题】:MYSQL Grouping and Having CountMYSQL 分组和计数
【发布时间】:2017-10-01 04:29:36
【问题描述】:

我有 4 个表:tblnames、tblcountry 和 tblcountry_link、tblgender。

tblcountry_link 将名称和国家/地区表连接在一起,因为名称可以包含多个国家/地区。

tbl 名称:

姓名ID |姓名 |性别ID

  1. 亚瑟 2
  2. 艾梅 1
  3. 奥布里 1
  4. 奥布里 2

tbl国家

国家 ID |国家 |国籍

  1. 阿富汗阿富汗人
  2. Argentina 阿根廷人

tblcountry_link

姓名ID |国家ID

  1. 1 | 1
  2. 1 | 2
  3. 2 | 1

tblgender

性别ID |性别

  1. 1 |女性
  2. 2 |男

我想要一个国家列表和每个国家或国籍的男女通用名称的数量,并带有我选择的首字母 - 所以对于字母 A;

  1. 阿富汗 (3)
  2. 阿根廷 (5)...

我知道如何通过使用“姓名”列上的计数和拥有以及按国籍分组来查找男女皆宜的姓名列表。

    {SELECT co.Nationality, COUNT( * ) 
    FROM (
    SELECT n.Name, COUNT( n.Name ) AS Countname, SUBSTR( Name, 1, 1 ) AS firstletter, g.Gender, cl.CountryID, c.Country, c.Nationality
    FROM tblnames AS n
    INNER JOIN tblgender AS g ON n.GenderID = g.GenderID
    INNER JOIN tblcountry_link AS cl ON cl.NameID = n.NameID
    INNER JOIN tblcountry AS c ON cl.CountryID = c.CountryID
    WHERE n.name LIKE CONCAT(  'A',  '%' ) 
    AND c.Nationality =  'Afghan'
    GROUP BY n.Name
    HAVING Countname >1
    ) AS co

这给了我结果阿富汗 (3)

但是,如果我删除 Where 子句的阿富汗部分,则结果不正确。我已尝试对此查询进行各种调整以获得我想要的结果,但结果看起来总是不正确。

我还可以获取两个性别的每个国家或国籍(如果我将其添加到 Where 子句中,则实际上是男性或女性)。

    {SELECT cl.CountryID, c.Country, COUNT( n.Name ) AS Countname
    FROM tblnames AS n
    INNER JOIN tblcountry_link AS cl ON cl.NameID = n.NameID
    INNER JOIN tblcountry AS c ON cl.CountryID = c.CountryID
    WHERE n.name LIKE CONCAT( 'A', '%' ) 
    GROUP BY c.Country}

国家 ID |国家 |计数名称

  1. 自动对焦 |阿富汗 | 624
  2. AR |阿根廷 | 28
  3. 上午 |亚美尼亚 | 5...

但是,我很难按国籍列出中性名称的数量。

我尝试将第一个示例中的Having 子句与后者结合起来,但这不起作用。 我尝试加入名称匹配的 2 个男性和女性子查询,但我无法正确分组和计数。 我还使用第一个示例尝试了派生表,但我只能使用 1 列,而这有 2。

任何帮助表示赞赏。

【问题讨论】:

    标签: mysql count duplicates grouping having


    【解决方案1】:

    试试这个。让我知道它是否有效。

    SELECT M.Country, MaleCount, FemaleCount FROM 
    (SELECT c.country, COUNT( n.Name ) AS MaleCount
        FROM tblnames AS n
        INNER JOIN tblcountry_link AS cl ON cl.NameID = n.NameID
        INNER JOIN tblcountry AS c ON cl.CountryID = c.CountryID
        WHERE n.name LIKE 'A%'
        AND GenderID = 2
        GROUP BY c.Country) AS M,
    (SELECT c.country, COUNT( n.Name ) AS FemaleCount
            FROM tblnames AS n
            INNER JOIN tblcountry_link AS cl ON cl.NameID = n.NameID
            INNER JOIN tblcountry AS c ON cl.CountryID = c.CountryID
            WHERE n.name LIKE 'A%'
            AND GenderID = 1
            GROUP BY c.Country) AS F  
    WHERE M.country = F.country
    

    如果我做得对,您应该将结果集设置为国家、男性人数和女性人数,其中名称以 A 开头。可能有更好的方法。如果我想到更好的方法,我会编辑。

    【讨论】:

    • 这行得通,但这不是我想要的。我需要 count 列只计算男性和女性的名字 - 因此男女皆宜 - 按国家/地区分组。
    • 好的。我想我现在明白了。我将在几个小时内使用解决方案编辑我的帖子。如果尚未发布。
    【解决方案2】:

    我又尝试了使用派生表。我读过这个article。它是 TSQL 但同样的结构适用。我想我已经得到了下面的解决方案。

        SELECT a1.Country, COUNT(a1.Name) as NameCount FROM (
        SELECT cl.CountryID, c.Country, n.Name, COUNT( n.Name ) AS Countname
        FROM tblnames AS n
        INNER JOIN tblgender AS g ON n.GenderID = g.GenderID
        INNER JOIN tblcountry_link AS cl ON cl.NameID = n.NameID
        INNER JOIN tblcountry AS c ON cl.CountryID = c.CountryID
        WHERE n.name LIKE CONCAT( 'A', '%' ) 
        GROUP BY c.Nationality, n.Name
        HAVING Countname >1
        ORDER BY n.Name) as a1
        Group BY a1.Country
    

    这给了我结果:

    国家 |姓名计数

    1. 阿富汗 | 3
    2. 奥地利 | 2
    3. 中国 | 1...

    【讨论】:

    • 不错。我也在想同样的事情。对不起,我错过了最初理解你的问题。我可能会改变的一件事是 concat 函数。我会将其作为“A%”而不是 concat。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    相关资源
    最近更新 更多