MariaDB / MySQL TO_SECONDS和AGGREGATE函数

时间:2016-09-18 13:16:04

标签: mysql aggregate mariadb

我想使用带有聚合函数的TO_SECONDS(AVG,COUNT)来汇总我的表。但是,结果并不是我的预期。这是一个示例表:

MariaDB [test]> select * from mytable;
+----+---------------------+------+
| id | ts                  | val  |
+----+---------------------+------+
|  1 | 2016-01-01 01:02:03 |    1 |
|  2 | 2016-01-01 01:02:04 |    2 |
|  3 | 2016-01-01 01:02:04 |    3 |
|  4 | 2016-01-01 01:02:05 |    4 |
|  5 | 2016-01-01 01:02:05 |    5 |
+----+---------------------+------+

查询#1(确定):

MariaDB [test]> select to_seconds(ts) as tsec from mytable;
+-------------+
| tsec        |
+-------------+
| 63618829323 |
| 63618829324 |
| 63618829324 |
| 63618829325 |
| 63618829325 |
+-------------+

查询#2(?):

MariaDB [test]> select to_seconds(ts) as tsec, avg(val) mval from mytable group by tsec;
+------------+------+
| tsec       | mval |
+------------+------+
| 2147483647 |    3 |
+------------+------+

预期结果:

+-------------+------+
| tsec        | mval |
+-------------+------+
| 63618829323 |    1 |
| 63618829324 |  2.5 |
| 63618829325 |  4.5 |
+-------------+------+

SQL小提琴:http://sqlfiddle.com/#!9/17616a/6
MariaDB版本> mysql Ver 15.1使用readline 5.1分发10.1.17-MariaDB,用于Linux(x86_64)

当然我可以使用其他DATE / TIME函数(UNIX_TIMESTAMP等)来执行任务。但是,我想知道为什么结果不同。
我错过了什么?我是否误解了TO_SECONDS的用法?

2 个答案:

答案 0 :(得分:1)

这是一个奇怪的数据类型问题。以下工作正常:

select cast(to_seconds(ts) as decimal(20, 0)) as tsec, avg(val)
from mytable
group by tsec;

我不知道为什么to_seconds()的返回值足以在您选择它时存储该值,但在您使用group by时会转换为整数。

答案 1 :(得分:1)

我无法回答为什么会发生这种情况,但是请确认在MySQL ver中仍然会发生这种情况。 5.7.32,并提出一种解决方法。

示例:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span class="span" data-src="https://post.greatist.com/wp-content/uploads/sites/3/2020/02/322868_1100-1100x628.jpg">dog</span>

<span class="span" data-src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png">cat</span>

<br/>

<img class="img"/>

到目前为止一切顺利。现在,使用create table Foo (t datetime); insert into Foo values('2020-01-01 00:00:01'); insert into Foo values('2020-01-02 00:00:01'); insert into Foo values('2020-01-03 00:00:01'); select t, to_seconds(t) from Foo; +---------------------+---------------+ | t | to_seconds(t) | +---------------------+---------------+ | 2020-01-01 00:00:01 | 63745056001 | | 2020-01-02 00:00:01 | 63745142401 | | 2020-01-03 00:00:01 | 63745228801 | +---------------------+---------------+

group by

每行的select t, to_seconds(t) from Foo group by t; +---------------------+---------------+ | t | to_seconds(t) | +---------------------+---------------+ | 2020-01-01 00:00:01 | 2147483647 | | 2020-01-02 00:00:01 | 2147483647 | | 2020-01-03 00:00:01 | 2147483647 | +---------------------+---------------+ 值变为2147483647,等于2 ^ 31-1,即可以用有符号的4字节整数表示的最大正值。在不应该发生的情况下,这看起来像MySQL服务器内部的某种数据转换问题。

基本上,同一问题在2019年3月被报告为MySQL错误( https://bugs.mysql.com/bug.php?id=94612),但此后,该错误报告未添加除确认之外的任何活动。

有趣的是,如果我们使用 to_seconds(t) to_seconds(t) (从理论上讲,应该会产生相同的结果,因为无论如何我们都在to_seconds(max(t))上分组):

max(to_seconds(t))