sqlgroupbywith
㈠ 为什么在sql语句的GROUP BY里面不可以使用别名
这个跟SQL语句执行顺序有关系
1
2
3
4
5
6
7
8
9
(8)SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
(1)FROM <left_table>
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH {CUBE|ROLLUP}
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
你看,GROUP BY执行的顺序在 SELECT前面,所以他不可能使用到别名
㈡ mysql sql优化之 优化GROUP BY 和 DISTINCT
创建表tb_point 表
准备空的tb_box表
函数
编写存储过程,给tb_box表添加100万条数据
修改关联数据
好于
优于
在执行以下语句时会报错:
前面在 https://www.jianshu.com/p/95e50fd017ea 文章中有提到这个问题,是直接修改sql_mode将 ONLY_FULL_GROUP_BY直接干掉。但是在《高性能mysql》中有一段话是这样的:
那么既然指出不要直接修改 sql_mode,那么我们应该如何让冲突的GRUOPBY语句正确执行呢?
文中有提到,可以使用max()和min()函数来实现;但是这种方式使用max和min函数较真的人可能会说这样写的分组查询有问题,确实如此。但是如果更加在乎查询效率,这样做也无可厚非。
如果,实在无法接受使用上面那种方式的话,可以这样使用子查询的方式来进行查询:
书上对于这种方式有描述如下:
这样写更满足关系理论,但是成本有点高,因为子查询需要填充临时表,而子查询中创建的临时表是没有任何索引的。
作者认为这样写对性能有影响。
但是从我测得结果来看,子查询的耗时反而更少。性能反而更佳。这个子查询耗时0.4秒。而使用max方式耗时0.8秒。几乎一倍。我的mysql版本是 5.7.22-log
为了解其中的原因,我们查看它的执行计划:
可见,因为子查询而产生了一层 DERIVED 临时表,但是这个临时表的Extra字段有显示 Using index、key里面显示自建索引。说明用到了索引。这是查询性能可观的一个重要原因吧;
另外我分别使用 SHOW PROFILE命令查看各部分耗时,对比之下。没看到有哪部分耗时差别特别大,使用JOIN、MAX 耗时比上子查询耗时都差不多是1倍
有些时候对一没有建立索引的字段,进行GRUOP BY时。会产生Using filesort 文件内排序。因为GRUOP BY是在排序的基础上进行分组的。
如下面sql:
如果业务上不对排序有要求。那么就可以禁止GRUOP BY的排序:
这样就把Using filesort给干掉了! 执行时间 1.237
当然,多数情况是多排序有要求的。此时也可以在GRUOP BY后面使用DESC和ASC关键字,使分组的结果集按需要的方向排序。如下:
分组查询的一个变种就是要求mysql对分组结果再进行一次超级聚合。可以使用GROUP BY WITH ROLLUP 来实现这种逻辑,但可能性能不佳。因为通过查询计划分析出它是使用 Using temporary; Using filesort 来实现的。
使用WITH ROLLUP,查询时间2.531秒。不使用0.774 秒。
1、所以,很多时候。我们在应用程序中做超级聚合是最好的!
2、当然也可使用UNION ALL 来实现:
3、还可以通过FROM子句嵌套使用子查询:
㈢ sql语句中的groupby是什么意思
一、sql语句中的groupby是:GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
二、sql语句group by的高级语法:
1、写上一个创建表的 sql语句. 当然,我们也可以用设计图创建;
㈣ SQL中的Group By的查询过程多列分组的查询过程是怎样的
Group By子句
Group By子句可以将表的行划分为不同的组。分别总结每个组,这样就可以控制想要看见的详细信息的级别。
语法:
[ Group By [ ALL ] Group_By_expression[ ,...n ]
[ WITH { CUBE | ROLLUP } ] ]
参数说明:
ALL:包含所有组和结果集,甚至包含那些任何行都不满足WHERE子句指定的搜索条件的组和结果集。如果指定了ALL,将对组中不满足搜索条件的汇总列返回空值。不能用CUBE或ROLLUP运算符指定ALL。如果访问远程表的查询中有WHERE子句,则不支持Group By ALL操作。
Group_By_expression:对其执行分组的表达式。Group_By_expression也称为分组列。Group_By_expression可以是列或引用列的非聚合表达式。在选择列表内定义的列的别名不能用于指定分组列。对于不包含CUBE或ROLLUP的Group By子句,Group_By_ expression的项数受查询所涉及的Group By列的大小、聚合列和聚合值的限制。该限制从8060字节的限制开始,对保存中间查询结果所需的中间级工作表有8060字节的限制。如果指定了CUBE或ROLLUP,则最多只能有10个分组表达式。
CUBE:指定在结果集内不仅包含由Group By提供的正常行,还包含汇总行。在结果集内返回每个可能的组和子组组合的Group By汇总行。Group By汇总行在结果中显示为NULL,但可用来表示所有值。使用GroupING函数确定结果集内的空值是否是Group By汇总值。结果集内的汇总行数取决于Group By子句内包含的列数。Group By子句中的每个操作数(列)绑定在分组NULL下,并且分组适用于所有其他操作数(列)。由于CUBE返回每个可能的组和子组组合,因此,不论指定分组列所使用的是什么顺序,行数都相同。
ROLLUP:指定在结果集内不仅包含由Group By提供的正常行,还包含汇总行。按层次结构顺序,从组内的最低级别到最高级别汇总组。组的层次结构取决于指定分组列时所使用的顺序。更改分组列的顺序会影响在结果集内生成的行数。
使用Group By子句的注意事项。
(1)在SELECT子句的字段列表中,除了聚集函数外,其他所出现的字段一定要在Group By子句中有定义才行。例如“Group By A,B”,那么“SELECT SUM(A),C”就有问题,因为C不在Group By中,但是SUM(A)是可以的。
(2)SELECT子句的字段列表中不一定要有聚集函数,但至少要用到Group By子句列表中的一个项目。例如“Group By A,B,C”,则“SELECT A”是可以的。
(3)在SQL Server中text、ntext和image数据类型的字段不能作为Group By子句的分组依据。
(4)Group By子句不能使用字段别名。
1.按单列进行分组
Group By子句可以基于指定某一列的值将数据集合划分为多个分组,同一组内所有记录在分组属性上具有相同值。
示例:
把“student”表按照“性别”这个单列进行分组。在查询分析器中输入的SQL语句如下:
use student
select 性别
from student
Group By 性别
但仍然要强调SELECT子句必须与Group By后的子句或者是分组函数列相一致。
例如,由于下列查询中“姓名”列既不包含在Group By子句中,也不包含在分组函数中,所以是错误的。错误的SQL语句如下:
use student select 姓名,性别 from student Group By 性别
例如,在“grade”表中,按“学期”分组查询。SQL语句如下:
use studnet select 学期 from grade Group By 学期
2.按多列进行分组
Group By子句可以基于指定多列的值将数据集合划分为多个分组。
示例:
在“student”表中,按照“性别”和“年龄”列进行分组。在查询分析中输入的SQL语句如下:
use student
select 性别,年龄
from student
Group By 性别,年龄
在“student”表中,首先按照“性别”分组,然后再按照“年龄”分组。
再举一个例子,例如,在“grade”表中,按照“学号”和“课程代号”列进行分组。SQL语句如下:
use student
select 学号,课程代号 from grade Group By 学号,课程代号
按多列进行分组时有NULL组的是如何处理的。当表按多列进行分组时有NULL组,这时NULL被作为一个特定值处理,就像其他任何值一样。也就是说,如果在某个分组列中存在两个NULL,则按它们有相同的值那样处理,并将它们放在相同的组中。
示例:
在“grade”表中,按“学期”和“课程代号”列进行分组。在查询分析器中输入的SQL语句如下:
use student
select 学期,课程代号
from grade
Group By 学期,课程代号
3.与聚集函数一起使用
Group By子句是经常与聚集函数一起使用。如果SELECT子句中包含聚集函数,则计算每组的汇总值,当用户指定Group By时,选择列表中任一非聚集表达式内的所有列都应包含在Group By列表中,或者Group By表达式必须与选择列表表达式完全匹配。
示例:
在“student”表中,分别求男女生的平均年龄。在查询分析器中输入的SQL语句如下:
use student
select 性别,avg(年龄) as 平均年龄
from student
Group By 性别
例如,在“student”表中,分别求有多少个男生和女生。SQL语句如下:
use student
select 性别,count(性别) as 人数 from student Group By 性别
说明:关于聚合函数的详细讲解可参阅9.2.1节。
4.与HAVING子句一起使用
HAVING子句对Group By子句选择出来的结果进行再次筛选,最后输出符合HAVING子句中条件的记录。HAVING子句的语法与WHERE子句的语法相类似,惟一不同的是HAVING子句中可以包含聚合函数。
语法:
[HAVING <search_condition>]
参数说明:
<search_condition>:指定组或聚合应满足的搜索条件。当HAVING与Group By ALL一起使用时,HAVING 子句替代ALL。
示例:
在“student”表中,按“性别”分组求平均年龄,并且查询其平均年龄大于21的学生信息。在查询分析器中输入的SQL语句如下:
use student
select avg(年龄), 性别
from student
Group By 性别
having avg(年龄)>21
在“grade”表中,按“学期”分组求平均成绩,并且查询“平均成绩”大于93的课程信息。在查询分析器中输入的SQL语句如下:
+1 已赞过
㈤ sql中group by with rollup怎么用
CREATE TABLE #test (
Name VARCHAR(10),
[procere] CHAR(1),
model VARCHAR(5),
quantity INT
);
INSERT INTO #test
SELECT 'A', '1', 'φ50', 500 UNION ALL
SELECT 'A', '1', 'φ50', 600 UNION ALL
SELECT 'A', '1', 'φ100', 500 UNION ALL
SELECT 'A', '2', 'φ50', 700 UNION ALL
SELECT 'A', '2', 'φ100', 200 UNION ALL
SELECT 'B', '1', 'φ50', 1000;
SELECT
CASE
WHEN GROUPING(Name) = 1 THEN '总计'
WHEN GROUPING(Name) = 0 AND GROUPING([procere]) = 1 THEN Name + '合计'
WHEN GROUPING(Name) = 0 AND GROUPING([procere]) = 0 AND GROUPING([model]) = 1 THEN Name + '的' + [procere] + '小计'
ELSE Name
END AS Name,
CASE
WHEN GROUPING([model]) = 1 THEN ''
ELSE [procere]
END AS [procere],
ISNULL(model, '') AS model,
SUM(quantity) AS quantity
FROM
#test
group by
Name,
[procere],
model with rollup;
Name procere model quantity
----------------- --------- ----- -----------
A 1 φ100 500
A 1 φ50 1100
A的1小计 1600
A 2 φ100 200
A 2 φ50 700
A的2小计 900
A合计 2500
B 1 φ50 1000
B的1小计 1000
B合计 1000
总计 3500
(11 行受影响)
SQL Server 2008 Express 下测试通过.
㈥ SQL如何能在查询时,将一列数据加和,但返回数据时包含明细,也包含这个加合的数据
在sqlserver中这个是靠的group by的子句完成此功能的,比如with cube或者是with
rollup。