MYSQL分组和计数

时间:2017-05-03 11:11:28

标签: mysql count duplicates grouping having

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

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

tblnames:

NameID |名称| GenderID

  1. Arthur 2
  2. Aimee 1
  3. Aubrey 1
  4. Aubrey 2
  5. tblcountry

    CountryID |国家|国籍

    1. 阿富汗阿富汗
    2. 阿根廷阿根廷人
    3. tblcountry_link

      NameID | CountryID

      1. 1 | 1
      2. 1 | 2
      3. 2 | 1
      4. tblgender

        GenderID |性别

        1. 1 |女
        2. 2 |雄性
        3. 我想要一份国家名单以及每个国家或国籍的男女皆宜名字的计数以及我选择的首字母 - 所以对于字母A;

          1. 阿富汗(3)
          2. 阿根廷(5)......
          3. 我知道如何通过在“名称”列上使用“计数”和“拥有”并按国籍分组来查找男女皆宜的名称列表。

                {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}
            

            CountryID |国家| Countname

            1. AF |阿富汗| 624
            2. AR |阿根廷| 28
            3. AM |亚美尼亚| 5 ...
            4. 但是,我正在努力按国籍列出男女皆宜的名字。

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

              任何帮助表示感谢。

2 个答案:

答案 0 :(得分:0)

试试这个。如果有效,请告诉我。

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开头的女性人数。可能有更好的方法。如果我想到一个更好的方法,我会编辑。

答案 1 :(得分:0)

我还有另外一个使用派生表。我读过这个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

这给了我结果:

国家| NameCount

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