在多个列上使用group by

我理解GROUP BY x的意思。

但是GROUP BY x, y是如何工作的,它意味着什么?

1923848 次浏览

Group By X表示将所有X值相同的元素放在一组中

Group By X, Y表示把所有X和Y值相同的人放在一组

为了举例说明,假设我们有下表,与谁在大学参加什么科目有关:

Table: Subject_Selection
+---------+----------+----------+| Subject | Semester | Attendee |+---------+----------+----------+| ITB001  |        1 | John     || ITB001  |        1 | Bob      || ITB001  |        1 | Mickey   || ITB001  |        2 | Jenny    || ITB001  |        2 | James    || MKB114  |        1 | John     || MKB114  |        1 | Erica    |+---------+----------+----------+

当您仅在主题列上使用group by时;说:

select Subject, Count(*)from Subject_Selectiongroup by Subject

你会得到类似的东西:

+---------+-------+| Subject | Count |+---------+-------+| ITB001  |     5 || MKB114  |     2 |+---------+-------+

…因为ITB001有5个条目,MKB114有2个条目

如果我们要group by两列:

select Subject, Semester, Count(*)from Subject_Selectiongroup by Subject, Semester

我们会得到这个:

+---------+----------+-------+| Subject | Semester | Count |+---------+----------+-------+| ITB001  |        1 |     3 || ITB001  |        2 |     2 || MKB114  |        1 |     2 |+---------+----------+-------+

这是因为,当我们按两列分组时,它说的是“将它们分组,以便所有具有相同主题和学期的人都在同一个组中,然后计算所有聚合函数(计数、总和、平均值等)对于这些群体中的每一个”。在这个例子中,这可以通过这样一个事实来证明,当我们统计他们时,第一学期有人在做ITB001,第二学期有两个人在做。做MKB114的两个人都在第一学期,所以第二学期没有一行(没有数据适合“MKB114,第二学期”组)

希望这有道理。

在这里,我不仅要解释GROUP子句的使用,还要解释Aggregate函数的使用。

GROUP BY子句与聚合函数一起使用,按一列或多列对结果集进行分组。例如:

-- GROUP BY with one parameter:SELECT column_name, AGGREGATE_FUNCTION(column_name)FROM table_nameWHERE column_name operator valueGROUP BY column_name;
-- GROUP BY with two parameters:SELECTcolumn_name1,column_name2,AGGREGATE_FUNCTION(column_name3)FROMtable_nameGROUP BYcolumn_name1,column_name2;

记住这个命令:

  1. SELECT(用于从数据库中选择数据)

  2. from(子句用于列出表)

  3. WHERE(子句用于过滤记录)

  4. GROUP BY(子句可在SELECT语句中用于收集数据跨多个记录并将结果按一个或多个列分组)

  5. HAVING(子句与GROUP BY子句结合使用以将返回行的组限制为仅条件为是真的)

  6. ORDER BY(关键字用于对结果集进行排序)

如果您使用的是聚合函数,您可以使用所有这些,这是它们必须设置的顺序,否则您可能会收到错误。

聚合函数是:

MIN()返回给定列中的最小值

MAX()返回给定列中的最大值。

SUM()返回给定列中数值的总和

AVG()返回给定列的平均值

COUNT()返回给定列中值的总数

COUNT(*)返回表中的行数

SQL关于使用聚合函数的脚本示例:

假设我们需要找到总销售额大于950美元的销售订单。我们结合HAVING子句和GROUP BY子句来完成此操作:

SELECTorderId, SUM(unitPrice * qty) TotalFROMOrderDetailsGROUP BY orderIdHAVING Total > 950;

计算所有订单并将它们分组为CusterID并对结果从属排序。我们组合了COUNT函数和GROUP BYORDER BY子句和ASC

SELECTcustomerId, COUNT(*)FROMOrdersGROUP BY customerIdORDER BY COUNT(*) ASC;

检索平均单价大于10美元的类别,使用AVG函数结合GROUP BYHAVING子句:

SELECTcategoryName, AVG(unitPrice)FROMProducts pINNER JOINCategories c ON c.categoryId = p.categoryIdGROUP BY categoryNameHAVING AVG(unitPrice) > 10;

使用子查询中的MIN函数按每个类别获取较便宜的产品:

SELECT categoryId,productId,productName,unitPriceFROM Products p1WHERE unitPrice = (SELECT MIN(unitPrice)FROM Products p2WHERE p2.categoryId = p1.categoryId)

下面将向您展示如何在子查询中使用MAX函数选择最近的日期项商品日期”:

SELECT categoryId,productId,productName,unitPrice,productDateFROM Products p1WHERE productDate= (SELECT MAX(productDate)FROM Products p2WHERE p2.categoryId = p1.categoryId)

以下语句将类目ID产品ID列中具有相同值的行分组:

SELECTcategoryId, categoryName, productId, SUM(unitPrice)FROMProducts pINNER JOINCategories c ON c.categoryId = p.categoryIdGROUP BY categoryId, productId

用简单的英语从GROUP BY用两个参数我们正在做的是查找相似的值对并将计数添加到第3列。

查看下面的示例以供参考。这里我使用1872年至2020年国际足球比赛结果

+----------+----------------+--------+---+---+--------+---------+-------------------+-----+|       _c0|             _c1|     _c2|_c3|_c4|     _c5|      _c6|                _c7|  _c8|+----------+----------------+--------+---+---+--------+---------+-------------------+-----+|1872-11-30|        Scotland| England|  0|  0|Friendly|  Glasgow|           Scotland|FALSE||1873-03-08|         England|Scotland|  4|  2|Friendly|   London|            England|FALSE||1874-03-07|        Scotland| England|  2|  1|Friendly|  Glasgow|           Scotland|FALSE||1875-03-06|         England|Scotland|  2|  2|Friendly|   London|            England|FALSE||1876-03-04|        Scotland| England|  3|  0|Friendly|  Glasgow|           Scotland|FALSE||1876-03-25|        Scotland|   Wales|  4|  0|Friendly|  Glasgow|           Scotland|FALSE||1877-03-03|         England|Scotland|  1|  3|Friendly|   London|            England|FALSE||1877-03-05|           Wales|Scotland|  0|  2|Friendly|  Wrexham|              Wales|FALSE||1878-03-02|        Scotland| England|  7|  2|Friendly|  Glasgow|           Scotland|FALSE||1878-03-23|        Scotland|   Wales|  9|  0|Friendly|  Glasgow|           Scotland|FALSE||1879-01-18|         England|   Wales|  2|  1|Friendly|   London|            England|FALSE||1879-04-05|         England|Scotland|  5|  4|Friendly|   London|            England|FALSE||1879-04-07|           Wales|Scotland|  0|  3|Friendly|  Wrexham|              Wales|FALSE||1880-03-13|        Scotland| England|  5|  4|Friendly|  Glasgow|           Scotland|FALSE||1880-03-15|           Wales| England|  2|  3|Friendly|  Wrexham|              Wales|FALSE||1880-03-27|        Scotland|   Wales|  5|  1|Friendly|  Glasgow|           Scotland|FALSE||1881-02-26|         England|   Wales|  0|  1|Friendly|Blackburn|            England|FALSE||1881-03-12|         England|Scotland|  1|  6|Friendly|   London|            England|FALSE||1881-03-14|           Wales|Scotland|  1|  5|Friendly|  Wrexham|              Wales|FALSE||1882-02-18|Northern Ireland| England|  0| 13|Friendly|  Belfast|Republic of Ireland|FALSE|+----------+----------------+--------+---+---+--------+---------+-------------------+-----+

现在我将通过GROUP BY操作按相似的国家(第0列)和锦标赛(第1列)值对进行分组,

SELECT `_c5`,`_c7`,count(*)  FROM res GROUP BY `_c5`,`_c7`
+--------------------+-------------------+--------+|                 _c5|                _c7|count(1)|+--------------------+-------------------+--------+|            Friendly|  Southern Rhodesia|      11||            Friendly|            Ecuador|      68||African Cup of Na...|           Ethiopia|      41||Gold Cup qualific...|Trinidad and Tobago|       9||AFC Asian Cup qua...|             Bhutan|       7||African Nations C...|              Gabon|       2||            Friendly|           China PR|     170||FIFA World Cup qu...|             Israel|      59||FIFA World Cup qu...|              Japan|      61||UEFA Euro qualifi...|            Romania|      62||AFC Asian Cup qua...|              Macau|       9||            Friendly|        South Sudan|       1||CONCACAF Nations ...|           Suriname|       3||         Copa Newton|          Argentina|      12||            Friendly|        Philippines|      38||FIFA World Cup qu...|              Chile|      68||African Cup of Na...|         Madagascar|      29||FIFA World Cup qu...|       Burkina Faso|      30|| UEFA Nations League|            Denmark|       4||        Atlantic Cup|           Paraguay|       2|+--------------------+-------------------+--------+

说明:第一排的意思是南罗得西亚总共举行了11场友谊赛。

备注:在这种情况下,必须使用计数器列。