10bet网址
MySQL 8.0参考手册
相关文件10bet官方网站 下载本手册 从本手册中摘录

12.20.3 MySQL组合的处理

SQL-92及更早版本不允许选择列表的查询,拥有条件,或订购列表是指在中未命名的非共度列通过...分组条款。例如,在标准SQL-92中,此查询是非法的,因为不结识名称选择列表中的列不会出现在通过...分组

从订单中选择O.Custid,C.Name,Max(O.Payment),客户AS CHOURE O.Custid = C.Custid组的C.Custid;

在SQL-92中查询是合法的,名称必须从“选择”列表中省略列或命名通过...分组条款。

SQL:1999及更高版本允许每个可选功能T301的这种非共ggregate如果它们在功能上取决于通过...分组列:如果之间存在这样的关系名称保管,查询是合法的。例如,这是这种情况保管一个主要键顾客

MySQL实现了功能依赖性的检测。如果是仅限_full_group_by.SQL模式已启用(默认情况下),MySQL拒绝选择列表的查询,拥有条件,或订购列表是指既不指定的非共度列通过...分组条款,也没有在功能上取决于它们。

MySQL还允许在一个不命名的非格子列通过...分组sql时的子句仅限_full_group_by.如果此列限制为单个值,则启用模式,如以下示例所示:

MySQL>创建表MyTable( - > ID INT UNSIGNED NOT NULL MINITE键, - > VARCHAR(10), - > B int  - >);MySQL>插入MyTable  - >值(1,'ABC',1000), - >(2,'ABC',2000), - >(3,'Def',4000);mysql> set session sql_mode = sys.list_add(@@ sessient.sql_mode,'sock.full_group_by');MySQL>从MyTable中选择A,Sum(b),其中a ='abc';+ ------ + -------- + |a |总和(b)|+ ------ + -------- + |ABC |3000 | +------+--------+

还可以在中有一个以上的非伸缩列选择雇用时列出仅限_full_group_by.。在这种情况下,每个这样的列必须限制在单个值中在哪里条款,所有此类限制条件必须通过逻辑加入,如这里所示:

MySQL> Drop表(如果存在MyTable);MySQL>创建表MyTable( - > ID int unsigned not null主键, - > varchar(10), - > b varchar(10), - > c int  - >);MySQL>插入MyTable  - >值(1,'ABC','QRS',1000), - >(2,'ABC','TUV',2000), - >(3,'def','QRS','QRS',4000), - >(4,'def','tuv',8000), - >(5,'abc','qrs',16000), - >(6,'def','tuv',32000);mysql> select @@ sessient.sql_mode;+ -------------------------------------------------------- + |@@ sessient.sql_mode |+ -------------------------------------------------------- + |仅限_full_group_by,strict_trans_tables,no_engine_substitution |+ -------------------------------------------------------- + mysql>从mytable中选择一个,b,sum(c) - >其中a ='abc'和b ='qrs'; +------+------+--------+ | a | b | SUM(c) | +------+------+--------+ | abc | qrs | 17000 | +------+------+--------+

如果仅限_full_group_by.被禁用,一个MySQL扩展到标准SQL使用通过...分组允许选择列表,拥有条件,或订购即使列在功能上不依赖,列表也可以引用非共gregated列通过...分组列。这导致MySQL接受前面查询。在这种情况下,服务器可以自由地从每个组中选择任何值,因此除非它们是相同的,否则所选择的值是非法的,这可能不是您想要的。此外,每个组的值选择不能影响订购条款。结果集排序发生在选中值后以及订购不影响服务器选择的每个组中的值。禁用仅限_full_group_by.主要是有用的,当您知道的时候,由于数据的某些属性,每个非聚集列中的所有值都不命名通过...分组每个组都是一样的。

您可以在不禁用的情况下达到相同的效果仅限_full_group_by.通过使用Any_Value()要引用非共ggated列。

以下讨论演示了功能依赖性,错误消息MySQL在不存在功能依赖性时生成,以及导致MySQL在没有功能依赖性的情况下接受查询的方式。

此查询可能无效仅限_full_group_by.启用,因为不结识地址选择列表中的列未在其中命名通过...分组条款:

按名称从T组选择名称,地址,最大(年龄);

查询是否有效名称是一个主要的键T.或者是一个独特的没有空柱子。在这种情况下,MySQL认识到所选列在功能上取决于分组列。例如,如果名称是一个主键,它的值确定值地址因为每个组只有一个主键的一个值,因此只有一行。结果,选择中没有随机性地址在一个组中的值,无需拒绝查询。

查询无效(如果)无效名称不是主要键T.或一个独特的没有空柱子。在这种情况下,可以推断出功能依赖关系,发生错误:

mysql>从t组按名称选择名称,地址,最大(年龄);错误1055(42000):SELECT列表中的表达式#2不在组逐个子句中,并包含非指定列'MyDB.t.Address',其在功能上没有依赖于组BY子句中的列;这与sql_mode = soot_full_group_by不兼容

如果你知道的话,对于给定的数据集,每个名称实际上价值唯一地确定地址价值,地址有效地在功能上取决于名称。要告诉MySQL接受查询,您可以使用Any_Value()功能:

按名称从T组中选择名称,ANY_VALUE(地址),MAX(年龄);

或者,禁用仅限_full_group_by.

然而,前一个例子非常简单。特别是,您不太可能在一个主键列上组组,因为每个组都只包含一行。对于addtime例,展示了更复杂的查询中的功能依赖性,请参阅第12.20.4节“检测功能依赖”

如果查询具有聚合函数,否通过...分组子句,在“选择”列表中不能具有非共记性列,拥有条件,或订购列出仅限_full_group_by.启用:

mysql>从t中选择名称,最大(年龄);错误1140(42000):在没有组的聚合查询中,SELECT列表的表达式#1包含非聚集列'mydb.t.name';这与sql_mode = soot_full_group_by不兼容

没有通过...分组,有一个单一的群体,它是不确定的名称为组选择的值。这里也,Any_Value()可以使用,如果它是无关紧要的名称值MySQL选择:

从t中选择Any_Value(name),max(年龄);

仅限_full_group_by.还会影响使用的查询的处理清楚的订购。考虑表的情况T.有三列C1.C2., 和C3.包含这些行:

C1 C2 C3 1 2 A 3 4 B 1 2 C.

假设我们执行以下查询,期待结果订购C3.

C3从T订单中选择不同的C1,C2;

要订购结果,必须首先消除重复项。但是这样做,我们应该保留第一行还是第三排?这个任意选择会影响保留的值C3.,这反过来影响订购并使其任意。为防止此问题,具有查询清楚的订购如果有的话,被拒绝无效订购表达式不满足这些条件中的至少一个:

  • 表达式等于SELECT列表中的表达式

  • 表达式引用并属于查询的所选表的所有列都是选择列表的元素

标准SQL的另一个MySQL扩展允许引用拥有在“选择”列表中的锯齿表达式的子句。例如,以下查询返回名称仅在表中发生一次的值命令

按命令组从命名组(name)= 1的名称中选择名称,计数(名称);

MySQL Extension允许使用别名拥有汇总列的子句:

选择名称,计数(name)按命令组的名称为c = 1;

标准SQL仅允许列表达式通过...分组条文,所以这样的陈述是无效的,因为地板(价值/ 100)是非umolumn表达式:

从中选择ID,Floor(Value / 100)tbl_name.小组依ID,楼层(价值/ 100);

MySQL扩展了标准SQL以允许非展示表达式通过...分组子句并考虑前面的陈述有效。

标准SQL也不允许别名通过...分组条款。MySQL扩展标准SQL以允许别名,因此另一种写入查询的方法如下:

从中选择ID,楼层(值/ 100)作为Valtbl_name.由ID,VAL;

别名被认为是一个列表达通过...分组条款。

在存在非增强中的存在通过...分组子句,MySQL在“选择”列表中识​​别该表达式和表达式之间的平等。这意味着仅限_full_group_by.启用了SQL模式,查询包含组由ID,地板(价值/ 100)是有效的,因为这也是如此地面()表达式发生在“选择”列表中。但是,MySQL不会试图识别功能依赖通过...分组非询问表达式,因此以下查询无效仅限_full_group_by.启用,即使第三选择表达式是简单的公式ID柱子和柱子地面()表达式在通过...分组条款:

从中选择ID,Floor / 100),ID +楼层(值/ 100)tbl_name.小组依ID,楼层(价值/ 100);

解决方法是使用派生表:

选择ID,F,ID + F(选择ID,Floor(Value / 100)为ftbl_name.按ID,地板(值/ 100))为DT;