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;