关于group by命令如何在mysql中工作,我有点困惑.
假设我有一张桌子:
mysql> select recordID, IPAddress, date, httpMethod from Log_Analysis_Records_dalhousieShort;
+----------+-----------------+---------------------+-------------------------------------------------+
| recordID | IPAddress | date | httpMethod |
+----------+-----------------+---------------------+-------------------------------------------------+
| 1 | 64.68.88.22 | 2003-07-09 00:00:21 | GET /news/science/cancer.shtml HTTP/1.0 |
| 2 | 64.68.88.166 | 2003-07-09 00:00:55 | GET /news/internet/xml.shtml HTTP/1.0 |
| 3 | 129.173.177.214 | 2003-07-09 00:01:23 | GET / HTTP/1.1 |
| 4 | 129.173.177.214 | 2003-07-09 00:01:23 | GET /include/fcs_style.css HTTP/1.1 |
| 5 | 129.173.177.214 | 2003-07-09 00:01:23 | GET /include/main_page.css HTTP/1.1 |
| 6 | 129.173.177.214 | 2003-07-09 00:01:23 | GET /images/bigportaltopbanner.gif HTTP/1.1 |
| 7 | 129.173.177.214 | 2003-07-09 00:01:23 | GET /images/right_1.jpg HTTP/1.1 |
| 8 | 64.68.88.165 | 2003-07-09 00:02:43 | GET /studentservices/responsible.shtml HTTP/1.0 |
| 9 | 64.68.88.165 | 2003-07-09 00:02:44 | GET /news/sports/basketball.shtml HTTP/1.0 |
| 10 | 64.68.88.34 | 2003-07-09 00:02:46 | GET /news/science/space.shtml HTTP/1.0 |
| 11 | 129.173.159.98 | 2003-07-09 00:03:46 | GET / HTTP/1.1 |
| 12 | 129.173.159.98 | 2003-07-09 00:03:46 | GET /include/fcs_style.css HTTP/1.1 |
| 13 | 129.173.159.98 | 2003-07-09 00:03:46 | GET /include/main_page.css HTTP/1.1 |
| 14 | 129.173.159.98 | 2003-07-09 00:03:48 | GET /images/bigportaltopbanner.gif HTTP/1.1 |
| 15 | 129.173.159.98 | 2003-07-09 00:03:48 | GET /images/left_1g.jpg HTTP/1.1 |
| 16 | 129.173.159.98 | 2003-07-09 00:03:48 | GET /images/webcam.gif HTTP/1.1 |
+----------+-----------------+---------------------+-------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
当我执行这个语句时,它如何选择recordID要包括哪个,因为有一系列的recordIDs是正确的?它只是选择匹配的第一个吗?
mysql> select recordID, IPAddress, date, httpMethod from Log_Analysis_Records_dalhousieShort GROUP BY IPADDRESS;
+----------+-----------------+---------------------+-------------------------------------------------+
| recordID | IPAddress | date | httpMethod |
+----------+-----------------+---------------------+-------------------------------------------------+
| 11 | 129.173.159.98 | 2003-07-09 00:03:46 | GET / HTTP/1.1 |
| 3 | 129.173.177.214 | 2003-07-09 00:01:23 | GET / HTTP/1.1 |
| 8 | 64.68.88.165 | 2003-07-09 00:02:43 | GET /studentservices/responsible.shtml HTTP/1.0 |
| 2 | 64.68.88.166 | 2003-07-09 00:00:55 | GET /news/internet/xml.shtml HTTP/1.0 |
| 1 | 64.68.88.22 | 2003-07-09 00:00:21 | GET /news/science/cancer.shtml HTTP/1.0 |
| 10 | 64.68.88.34 | 2003-07-09 00:02:46 | GET /news/science/space.shtml HTTP/1.0 |
+----------+-----------------+---------------------+-------------------------------------------------+
6 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
对于这个表,这些max(date)和min(date)值似乎对我来说是合乎逻辑的,但我对如何选择recordID和httpMethod在哪里感到困惑.
在一个命令中使用两个聚合函数是否安全?
mysql> select recordID, IPAddress, min(date), max(date), httpMethod from Log_Analysis_Records_dalhousieShort GROUP BY IPADDRESS;
+----------+-----------------+---------------------+---------------------+-------------------------------------------------+
| recordID | IPAddress | min(date) | max(date) | httpMethod |
+----------+-----------------+---------------------+---------------------+-------------------------------------------------+
| 11 | 129.173.159.98 | 2003-07-09 00:03:46 | 2003-07-09 00:03:48 | GET / HTTP/1.1 |
| 3 | 129.173.177.214 | 2003-07-09 00:01:23 | 2003-07-09 00:01:23 | GET / HTTP/1.1 |
| 8 | 64.68.88.165 | 2003-07-09 00:02:43 | 2003-07-09 00:02:44 | GET /studentservices/responsible.shtml HTTP/1.0 |
| 2 | 64.68.88.166 | 2003-07-09 00:00:55 | 2003-07-09 00:00:55 | GET /news/internet/xml.shtml HTTP/1.0 |
| 1 | 64.68.88.22 | 2003-07-09 00:00:21 | 2003-07-09 00:00:21 | GET /news/science/cancer.shtml HTTP/1.0 |
| 10 | 64.68.88.34 | 2003-07-09 00:02:46 | 2003-07-09 00:02:46 | GET /news/science/space.shtml HTTP/1.0 |
+----------+-----------------+---------------------+---------------------+-------------------------------------------------+
6 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
And*_*eKR 13
通常在没有聚合函数的select表达式中列出字段时使用GROUP BY是无效的SQL并且应该抛出错误.
但是,MySQL允许这样做,只需随机选择一个值.尽量避免它,因为它令人困惑.
要禁止这一点,您可以在运行时说:
SET sql_mode := CONCAT('ONLY_FULL_GROUP_BY,',@@sql_mode);
或使用配置值和/或命令行选项sql-mode.
是的,列出两个聚合函数是完全有效的.
小智 5
因为我显然是新手,所以我无法发布有用的图片,所以我会尝试用文字来做到这一点......
我刚刚对此进行了测试,似乎不在 GROUP BY 中的字段的值将使用与 group by 条件匹配的第一行的值。这也将解释其他人在选择不在 group by 子句中的列时所经历的感知“随机性”。
例子:
创建一个名为“test”的表,其中包含两个名为“col1”和“col2”的列,数据如下所示:
Col1 Col2
1 2
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
然后运行以下查询:
通过 col2 desc
从测试
顺序中选择 col1,col2
你会得到这样的结果:
1 3
2 3
3 3
1 2
1 2
2 2
3 2
2 1
3 1
现在考虑以下查询:
select groupTable.col1,groupTable.col2
from (
select col1,col2
from test
order by col2 desc
) groupTable
group by groupTable.col1
order by groupTable.col1 desc
你会得到这样的结果:
3 3
2 3
1 3
将子查询更改为 asc:
按 col2 asc
从测试
顺序中选择 col1,col2
结果:
2 1
3 1
1 2
1 2
2 2
3 2
1 3
2 3
3 3
再次使用它作为子查询的基础:
select groupTable.col1,groupTable.col2
from (
select col1,col2
from test
order by col2 asc
) groupTable
group by groupTable.col1
order by groupTable.col1 desc
结果:
3 1
2 1
1 2
现在您应该能够看到子查询的顺序如何影响为已选择但不在 group by 子句中的字段选择哪些值。这将解释其他人提到的感知“随机性”,因为如果子查询(或缺少)没有与 ORDER BY 子句结合,那么 mysql 将在行出现时抓取它们,但是通过在子查询中定义排序顺序,您能够控制这种行为并获得可预测的结果。
| 归档时间: |
|
| 查看次数: |
4604 次 |
| 最近记录: |