为什么我们在 SQL 查询中使用 Group by 1 和 Group by 1,2,3?

urs*_*ion 36 mysql syntax plsql group-by

在 SQL 查询中,我们确实使用 Group by 子句来应用聚合函数。

  • 但是在 Group by 子句中使用数值而不是列名的目的是什么?例如:按 1 分组。

Aar*_*and 36

恕我直言,这实际上是一件非常糟糕的事情,并且大多数其他数据库平台都不支持它。

人们这样做的原因:

  • 他们很懒——我不知道为什么人们认为通过编写简洁的代码而不是输入额外的 40 毫秒来获得更多文字代码来提高他们的生产力。

不好的原因:

  • 它不是自我记录- 有人将不得不解析 SELECT 列表以找出分组。它实际上在 SQL Server 中会更清楚一点,它不支持像 MySQL 那样的牛仔谁知道会发生什么分组。

  • 它很脆弱- 有人进来并更改 SELECT 列表,因为业务用户想要不同的报告输出,现在您的输出一团糟。如果您在 GROUP BY 中使用了列名,则 SELECT 列表中的顺序将无关紧要。

SQL Server 支持 ORDER BY [ordinal];这里有一些反对使用它的平行论据:


小智 12

考虑以下情况:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-06-01 | Apps         |         3 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Videos       |         2 |
| 2016-06-01 | Apps         |         2 |
+------------+--------------+-----------+
Run Code Online (Sandbox Code Playgroud)

将应用程序和应用程序视为同一服务,您必须找出每项服务每天的下载次数。通过分组date, services会导致AppsApplications被视为单独的服务。

在这种情况下,查询将是:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services
Run Code Online (Sandbox Code Playgroud)

和输出:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Apps         |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Apps         |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+
Run Code Online (Sandbox Code Playgroud)

但这不是您想要的,因为需要对应用程序和应用程序进行分组。所以,我们能做些什么?

一种方法是使用表达式或函数替换Apps,然后将它们按服务分组为:ApplicationsCASEIF

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services
Run Code Online (Sandbox Code Playgroud)

但是,这仍然群体服务考虑Apps,并Applications为不同的服务和提供同样的输出如以前:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Applications |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+
Run Code Online (Sandbox Code Playgroud)

对列号进行分组允许您对别名列上的数据进行分组。

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;
Run Code Online (Sandbox Code Playgroud)

从而为您提供所需的输出,如下所示:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+
Run Code Online (Sandbox Code Playgroud)

我读过很多次,这是一种在别名列上编写查询或分组的懒惰方式在 MySQL 中不起作用,但这是对别名列进行分组的方式。

这不是编写查询的首选方式,仅当您确实需要对别名列进行分组时才使用它。


Rol*_*DBA 9

MySQL 允许您GROUP BY使用别名(列别名问题)。这比GROUP BY使用数字要好得多。

谷歌有很多使用它的例子以及为什么很多人停止使用它。

为了跟你说实话,我还没有使用的列号码ORDER BY,并GROUP BY从1996年开始(我当时做的Oracle PL / SQL开发)。使用列号确实是为老手们准备的,向后兼容性允许这样的开发人员使用 MySQL 和其他仍然允许它的 RDBMS。