用 mySQL 计算“子列”

Posted

技术标签:

【中文标题】用 mySQL 计算“子列”【英文标题】:Counting "subcolumns" with mySQL 【发布时间】:2021-11-19 20:43:04 【问题描述】:

各位让我说清楚。我正在学习 mysql 并练习函数“count()”。我有一个名为“City”的表,其中有 ID、名称、CountryCode、区和人口。我的第一个想法是按国家/地区了解我有多少个城市

SELECT *, Count(name) as "total" FROM world.city GROUP BY countrycode;

成功了,创建了一个额外的列,其中包含每个国家/地区的城市数量。我想通过计算不同行的数量来知道我有多少个国家(我知道在 WorkBench 的底部有这个信息,但我想知道让这个信息出现在我的查询中)。我尝试添加一个 Count(CountryCode),但它并没有像我预期的那样工作,出现了一个数字 4079,这是我拥有的城市总数。我发现我的“Count()”正在计算每个国家/地区内的行数,而不是计算每个国家/地区的代码数量。有可能得到这些信息吗?

【问题讨论】:

您的查询应该会出错,因为您选择了所有列但仅按一个分组 SELECT COUNT(DISTINCT countrycode) FROM world.city 【参考方案1】:

(适合新手的迷你课程。)

首先要了解的是COUNT(*)COUNT的常用用法。你得到行数。相比之下,COUNT(name) 计算具有非 NULL name 值的行数。

然后是使用DISTINCT 的方法。它不是一个函数。所以COUNT(DISTINCT a,b)计算ab的不同组合的数量。而COUNT(DISTINCT(a)) 虽然它工作得“很好”和“正确”,但括号是多余的。所以使用COUNT(DISTINCT a)

不要将*GROUP BY 一起使用。也就是说,SELECT *, ... GROUP BY ... 是不合适的。说出类似您的查询的通常方式是

选择国家代码,COUNT(*) AS "total" 来自世界城市 按国家代码分组;

对于加拿大的省份(我恰好有一张表格):

SELECT province, COUNT(*) AS "total" FROM world.canada GROUP BY province;

+---------------------------+-------+
| province                  | total |
+---------------------------+-------+
| Alberta                   |   573 |
| British Columbia          |   716 |
| Manitoba                  |   299 |
| New Brunswick             |   210 |
| Newfoundland and Labrador |   474 |
| Northwest Territories     |    94 |
| Nova Scotia               |   331 |
| Nunavut                   |   107 |
| Ontario                   |   891 |
| Prince Edward Island      |    57 |
| Quebec                    |  1045 |
| Saskatchewan              |   573 |
| Yukon                     |   114 |
+---------------------------+-------+

请注意,一些城市出现在多个省份:

SELECT COUNT(DISTINCT city), COUNT(*) FROM world.canada;
+----------------------+----------+
| COUNT(DISTINCT city) | COUNT(*) |
+----------------------+----------+
|                 5248 |     5484 |
+----------------------+----------+

咀嚼这个;还有更多需要学习的经验:

  SELECT city, COUNT(*) AS ct, GROUP_CONCAT(DISTINCT state)
           FROM world.us
           GROUP BY city
           ORDER BY COUNT(*)
           DESC LIMIT 11;
  +-------------+----+----------------------------------+
  | city        | ct | GROUP_CONCAT(DISTINCT state)     |
  +-------------+----+----------------------------------+
  | Springfield | 11 | FL,IL,MA,MO,NJ,OH,OR,PA,TN,VA,VT |
  | Clinton     | 10 | CT,IA,MA,MD,MO,MS,OK,SC,TN,UT    |
  | Madison     |  8 | AL,CT,IN,ME,MS,NJ,SD,WI          |
  | Lebanon     |  8 | IN,ME,MO,NH,OH,OR,PA,TN          |
  | Auburn      |  7 | AL,CA,IN,ME,NH,NY,WA             |
  | Burlington  |  7 | IA,MA,NC,NJ,VT,WA,WI             |
  | Washington  |  7 | DC,IL,IN,MO,NC,PA,UT             |
  | Farmington  |  7 | ME,MI,MN,MO,NH,NM,UT             |
  | Canton      |  6 | GA,IL,MA,MI,MS,OH                |
  | Monroe      |  6 | GA,LA,MI,NC,WA,WI                |
  | Lancaster   |  6 | CA,NY,OH,PA,SC,TX                |
  +-------------+----+----------------------------------+

关于一个国家的城市数量,属于Countries的表,不在Cities的表中。然后当你想把它们放在一起时使用JOIN

【讨论】:

PS -- 我的数据显示,在 39 个国家/地区有 57 个城市名为“Mala”。以及遍布 28 个国家/地区的 317 家圣安东尼奥。

以上是关于用 mySQL 计算“子列”的主要内容,如果未能解决你的问题,请参考以下文章

7-1 最大子列和问题

最大子列和问题

7-1 最大子列和问题 (20分)

复杂度_最大子列和问题

算法第二章上机实践报告

用 Mysql 计算中位数