2017-05-03 74 views
0

我有4个表:tblnames,tblcountry和tblcountry_link,tblgender。MYSQL分组和计数

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

tblnames:

NameID |名称| GenderID

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

tblcountry

CountryID |国家|国籍

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

tblcountry_link

填充NameID | CountryID

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

tblgender

GenderID |性别

  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} 

CountryID |国家|计数名称

  1. AF |阿富汗| 624
  2. AR |阿根廷| 28
  3. AM |亚美尼亚| 5 ...

但是,我努力列出国籍的男女皆宜的名字的数量。

我曾尝试合并第一例后者HAVING子句,但这不起作用。 我曾尝试加入男性和女性的2个子查询名称匹配,但我无法得到这个组和计数正确。 我还试图使用第一例的派生表,但我只能用1柱并且这具有2

理解任何帮助。

回答

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开头的号码的数量有可能是一个更好的办法。如果我想到更好的方法,我会编辑。

+0

这工作,但它不是我想要的。我需要count列来计算那些既男性又女性的名字 - 因此男女皆宜 - 按国家分组。 – thunderousity

+0

好的。我想我现在得到它。我会在几个小时内用解决方案编辑我的帖子。如果还没有发布。 – noyanc

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

不错。我正在考虑同样的事情。抱歉,我最初无法理解你的问题。有一件事我可能会改变是concat函数。我会以'A%'来代替concat。 – noyanc