MySQL UNION ALL如何运行agregate函数?

我有一些SQL代码,它正是我想要它的工作方式:

select 10 as number, "Checklist 10 Foo" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
from checklist_10
union all
select 11 as number, "Checklist 11 Bar" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
from checklist_11
union all
select 12 as number, "Checklist 12 Baz" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
from checklist_12

group by callsign, number
order by max_ts

结果:

number,name,max(id),max_ts,callsign,max(time_hint_utc),count(*)
10,Checklist 10 Foo,2,1486554484635,VRTEST,2017-02-08 12:21:32,2
11,Checklist 11 Bar,2,1486554490674,VRTEST,2017-02-08 12:21:39,2
12,Checklist 12 Baz,2,1486554496378,VRTEST,2017-02-08 12:21:44,2
12,Checklist 12 Baz,3,1486554496379,VRTEST2,2017-02-08 12:21:45,1

特别是,我看到max()和count()的正确结果,即每个呼号/数字组合的最大值和数量,而不是单个选择的最大值和数量.

这怎么办?聚合函数看起来像是在表级选择中,但它们的功能就好像它们是联合all alled结果的函数.

附:很抱歉提问,当唯一的问题是我缺乏理解.

使用表格描述更新:

mysql> describe checklist_10;
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| Field         | Type                                                         | Null | Key | Default | Extra          |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned                                          | NO   | PRI | NULL    | auto_increment |
| ts            | bigint(20) unsigned                                          | NO   |     | NULL    |                |
| callsign      | varchar(20)                                                  | NO   |     | NULL    |                |
| smg_id        | tinyint(3) unsigned                                          | NO   |     | NULL    |                |
| time          | int(11)                                                      | NO   |     | NULL    |                |
| time_hint_utc | datetime                                                     | NO   |     | NULL    |                |
| reason        | enum('UNKNOWN','PERIODIC','SHIFT','MENU','EVENT','DECLINED') | NO   |     | NULL    |                |
| foo0          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo1          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo2          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo3          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo4          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo5          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo6          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo7          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo8          | tinyint(1)                                                   | NO   |     | NULL    |                |
| foo9          | tinyint(1)                                                   | NO   |     | NULL    |                |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)

mysql> describe checklist_11;
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| Field         | Type                                                         | Null | Key | Default | Extra          |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned                                          | NO   | PRI | NULL    | auto_increment |
| ts            | bigint(20) unsigned                                          | NO   |     | NULL    |                |
| callsign      | varchar(20)                                                  | NO   |     | NULL    |                |
| smg_id        | tinyint(3) unsigned                                          | NO   |     | NULL    |                |
| time          | int(11)                                                      | NO   |     | NULL    |                |
| time_hint_utc | datetime                                                     | NO   |     | NULL    |                |
| reason        | enum('UNKNOWN','PERIODIC','SHIFT','MENU','EVENT','DECLINED') | NO   |     | NULL    |                |
| bar0          | tinyint(1)                                                   | NO   |     | NULL    |                |
| bar1          | tinyint(1)                                                   | NO   |     | NULL    |                |
| bar2          | tinyint(1)                                                   | NO   |     | NULL    |                |
| bar3          | tinyint(1)                                                   | NO   |     | NULL    |                |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)

mysql> describe checklist_12;
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| Field         | Type                                                         | Null | Key | Default | Extra          |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned                                          | NO   | PRI | NULL    | auto_increment |
| ts            | bigint(20) unsigned                                          | NO   |     | NULL    |                |
| callsign      | varchar(20)                                                  | NO   |     | NULL    |                |
| smg_id        | tinyint(3) unsigned                                          | NO   |     | NULL    |                |
| time          | int(11)                                                      | NO   |     | NULL    |                |
| time_hint_utc | datetime                                                     | NO   |     | NULL    |                |
| reason        | enum('UNKNOWN','PERIODIC','SHIFT','MENU','EVENT','DECLINED') | NO   |     | NULL    |                |
| baz0          | tinyint(1)                                                   | NO   |     | NULL    |                |
| baz1          | tinyint(1)                                                   | NO   |     | NULL    |                |
| baz2          | tinyint(1)                                                   | NO   |     | NULL    |                |
| baz3          | tinyint(1)                                                   | NO   |     | NULL    |                |
| baz4          | tinyint(1)                                                   | NO   |     | NULL    |                |
+---------------+--------------------------------------------------------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)

数据:

mysql> select * from checklist_10;
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+------+------+------+------+------+
| id | ts            | callsign | smg_id | time       | time_hint_utc       | reason   | foo0 | foo1 | foo2 | foo3 | foo4 | foo5 | foo6 | foo7 | foo8 | foo9 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+------+------+------+------+------+
|  1 | 1486554385343 | VRTEST   |      7 | 1486556393 | 2017-02-08 12:19:53 | PERIODIC |    1 |    1 |    0 |    0 |    1 |    1 |    0 |    1 |    0 |    0 |
|  2 | 1486554484635 | VRTEST   |      7 | 1486556492 | 2017-02-08 12:21:32 | SHIFT    |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+------+------+------+------+------+
2 rows in set (0.00 sec)

mysql> select * from checklist_11;
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+
| id | ts            | callsign | smg_id | time       | time_hint_utc       | reason   | bar0 | bar1 | bar2 | bar3 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+
|  1 | 1486554457077 | VRTEST   |      7 | 1486556465 | 2017-02-08 12:21:05 | PERIODIC |    0 |    0 |    0 |    0 |
|  2 | 1486554490674 | VRTEST   |      7 | 1486556499 | 2017-02-08 12:21:39 | SHIFT    |    1 |    1 |    1 |    1 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+
2 rows in set (0.00 sec)

mysql> select * from checklist_12;
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+
| id | ts            | callsign | smg_id | time       | time_hint_utc       | reason   | baz0 | baz1 | baz2 | baz3 | baz4 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+
|  1 | 1486554476903 | VRTEST   |      7 | 1486556485 | 2017-02-08 12:21:25 | PERIODIC |    1 |    1 |    1 |    1 |    1 |
|  2 | 1486554496378 | VRTEST   |      7 | 1486556504 | 2017-02-08 12:21:44 | SHIFT    |    1 |    1 |    1 |    1 |    1 |
|  3 | 1486554496379 | VRTEST2  |      7 | 1486556505 | 2017-02-08 12:21:45 | SHIFT    |    1 |    1 |    1 |    1 |    1 |
+----+---------------+----------+--------+------------+---------------------+----------+------+------+------+------+------+
3 rows in set (0.00 sec)

没有1054错误:

mysql> select 10 as number, "Checklist 10 Foo" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
    -> from checklist_10
    -> union all
    -> select 11 as number, "Checklist 11 Bar" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
    -> from checklist_11
    -> union all
    -> select 12 as number, "Checklist 12 Baz" as name, max(id), max(ts) as max_ts, callsign, max(time_hint_utc), count(*)
    -> from checklist_12
    -> 
    -> group by callsign, number
    -> order by max_ts;
+--------+------------------+---------+---------------+----------+---------------------+----------+
| number | name             | max(id) | max_ts        | callsign | max(time_hint_utc)  | count(*) |
+--------+------------------+---------+---------------+----------+---------------------+----------+
|     10 | Checklist 10 Foo |       2 | 1486554484635 | VRTEST   | 2017-02-08 12:21:32 |        2 |
|     11 | Checklist 11 Bar |       2 | 1486554490674 | VRTEST   | 2017-02-08 12:21:39 |        2 |
|     12 | Checklist 12 Baz |       2 | 1486554496378 | VRTEST   | 2017-02-08 12:21:44 |        2 |
|     12 | Checklist 12 Baz |       3 | 1486554496379 | VRTEST2  | 2017-02-08 12:21:45 |        1 |
+--------+------------------+---------+---------------+----------+---------------------+----------+
4 rows in set (0.00 sec)

最佳答案 它不像你想象的那样工作.根据
documentation,

If you use a group function in a statement containing no GROUP BY clause, it is equivalent to grouping on all rows.

所以这里发生的是你有两个隐含的分组(无论你是否在数据中有不同的呼号,总是只返回一行)和一个显式分组,实际上只对最后一个选择进行分组.

因此,对于MySQL,您的查询看起来和行为类似

(select 10 as number, "Checklist 10 Foo" as name, max(id), max(ts) as max_ts, 
    callsign, max(time_hint_utc), count(*)
from checklist_10)

union all

(select 11 as number, "Checklist 11 Bar" as name, max(id), max(ts) as max_ts, 
   callsign, max(time_hint_utc), count(*)
from checklist_11)

union all

(select 12 as number, "Checklist 12 Baz" as name, max(id), max(ts) as max_ts, 
   callsign, max(time_hint_utc), count(*)
from checklist_12
group by callsign, number)

order by max_ts

你可以试试这个,例如通过更改checklist_10或checklist_11中某一行的呼号.它不会按预期分组.或者你可以,例如在第一个或最后一个查询中将别名编号重命名为number1.它将(仅)在第一种情况下工作,在后一种情况下,group by现在无法找到列号.

此外,在您的情况下,这仅在您禁用only_full_group_by sql模式时才有效,因为您的选择列表包含聚合函数以外的列.

点赞