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


26

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

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

3
order by 1仅在mysql> 提示时使用。在代码中,使用ORDER BY id ASC。请注意大小写,显式字段名称和显式排序方向。
dotancohen 2014年

Answers:


28

恕我直言,这实际上是一件坏事,大多数其他数据库平台均不支持。

人们这样做的原因:

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

不好的原因:

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

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

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


9

MySQL允许您GROUP BY使用别名(列别名问题)。这将好于GROUP BY处理数字。

Google有许多使用它的例子,以及为什么许多人停止使用它。

为了跟你说实话,我还没有使用的列号码ORDER BY,并GROUP BY从1996年开始(我当时做的Oracle PL / SQL开发)。实际上,使用列号是为了让旧时使用,并且向后兼容性使此类开发人员可以使用MySQL和其他仍允许它的RDBMS。


8

考虑以下情况:

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

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

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

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

并输出:

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

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

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

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

但这仍将考虑的服务和不同的服务分组AppsApplications并提供与以前相同的输出:

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

通过对列号进行分组,您可以将别名列上的数据分组。

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

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

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

我已经读过很多遍了,这是一种编写查询或对别名列进行分组的惰性方法,在MySQL中不起作用,但这是对别名列进行分组的方法。

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


但是,这仍然将服务视为应用程序和应用程序,将服务分组为不同的服务,并提供与以前相同的输出 ”。如果您为别名选择了其他名称(不冲突),这是否可以解决?
Daddy32 '18

3

没有正当理由使用它。它只是一个懒惰的快捷方式,专门设计用于使某些精打细算的开发人员以后很难弄清您的分组或排序,或者当有人更改列顺序时使代码惨败。体谅您的开发人员同伴,不要这样做。


0

这对我有用。该代码将行最多分为5组。

SELECT
USR.UID,
USR.PROFILENAME,
(
    CASE 
    WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
        @curRow := 0
    ELSE
        @curRow := @curRow + 1 
        /*@curRow := 1*/ /*AND @curCode := USR.UID*/
    END
) AS sort_by_total  
FROM
    SS_USR_USERS USR,
    (
        SELECT
            @curRow := 0,
            @curCode := ''
    ) rt
ORDER BY
    USR.PROFILENAME,
    USR.UID

结果如下

在此处输入图片说明


0
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;

SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;

考虑上面的查询:按1分组表示按第一列分组,按1,2分组表示按第一和第二列分组,按1,2,3分组表示按第一第二和第三列分组。例如:

1,2组

此图显示了按1,2分组的前两列,即未考虑dep_date的不同值来查找计数(计算计数时考虑了前两列的所有不同组合),而第二个查询结果是 1,2,3分组

图片。在这里,它考虑了所有前三列,并且有不同的值来找到计数,即按所有前三列进行分组(计算计数时要考虑前三列的所有不同组合)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.