SQL语句——08、聚集,分组,行转列

常用聚集函数

是对一组或一批数据进行综合操作后返回一个结果,如下:

count 行总数
avg 平均数
sum 列值和
max 最大值
min 最小值

用法说明

count([{distinct|all} ‘列名‘|*) 为列值时空不在统计之内,为*时包含空行和重复行

idle> select count(comm) from emp; 

COUNT(COMM)
-----------
4 

idle> select count(ename) from emp; 

COUNT(ENAME)
------------
14 

idle> select count(*) from emp; 

COUNT(*)
----------
14 

idle> select count(deptno) from emp; 

COUNT(DEPTNO)
-------------
14 

idle> select count(distinct deptno) from emp; 

COUNT(DISTINCTDEPTNO)
---------------------
3 

idle> select count(all deptno) from emp; 

COUNT(ALLDEPTNO)
----------------
14 

上面执行的聚集函数都是对所有记录统计,如果想分组统计(比如统计部门的平均值)需要使用group by,为了限制分组统计的结果需要使用having过滤

求出每个部门的平均工资 

idle> select deptno,avg(sal) from emp group by deptno; 

DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667 

分组再排序
idle> select deptno,avg(sal) from emp group by deptno order by deptno ; 

DEPTNO AVG(SAL)
---------- ----------
10 2916.66667
20 2175
30 1566.66667 

分组修饰列可以是未选择的列
idle> select avg(sal) from emp group by deptno order by deptno; 

AVG(SAL)
----------
2916.66667
2175
1566.66667 

如果在查询中使用了分组函数,任何不在分组函数中的列或表达式必须在group by子句中。因为分组函数是返回一行而其他列显示多行显示结果矛盾。

idle> select avg(sal) from emp ; 

AVG(SAL)
----------
2073.21429 

idle> select deptno,avg(sal) from emp;
select deptno,avg(sal) from emp
*
ERROR at line 1:
ORA-00937: not a single-group group function 

idle> select deptno,avg(sal) from emp group by deptno ; 

DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667 

idle> select deptno,avg(sal) from emp group by deptno order by job;
select deptno,avg(sal) from emp group by deptno order by job
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression 

group by 的过滤

查出平均工资大于2000的部门
idle> select deptno,avg(sal) avg from emp group by deptno where avg >2000;
select deptno,avg(sal) avg from emp group by deptno where avg >2000
*
ERROR at line 1:
ORA-00933: SQL command not properly ended 

group by后不能再接where子句过滤,where过滤只能加到group by前端这样又不能满足要求,对分组后的过滤要使用having。

idle> select deptno,avg(sal) avg from emp group by deptno having avg(sal) >2000; 

DEPTNO AVG
---------- ----------
20 2175
10 2916.66667 

分组函数的注意事项:

  1. 分组函数只能出现在select,order by,having,分析函数子句中
  2. 分组函数会忽略NULL 除了count(*)
  3. 分组函数中可以使用ALL或distinct;ALL是默认值,统计所有。加上distinct则只统计不同
  4. 如果选择的列里有普通列,表达式和分组列,那么普通列和表达式都必须出现在group by中 。

如下操作:得到t5表中有部分行是重复的,找出重复的行

SQL> create table t5 as select * from emp; 

Table created. 

SQL> insert into t5 select * from emp where deptno=20; 

5 rows created. 

SQL> commit; 

Commit complete. 

SQL>
查看:
select count(ename),ename from t5 group by ename having COUNT(ENAME) !=1;
删除: 不是函数,而是列名
delete t5 where rowid in (select max(rowid) from t5 group by ename having count(ename)>1); 

行转列

pivot(行专列)and unpivot(列转行)函数的使用

pivot(聚合函数 for 列名 in(类型)) ,其中 in(‘’) 中可以指定别名,in中还可以指定子查询,

比如 select distinct code from customers

select * from (select name, nums from demo) pivot (sum(nums) for name in (‘苹果‘, ‘橘子‘, ‘葡萄‘, ‘芒果‘));

select id , name, jidu, xiaoshou from Fruit unpivot (xiaoshou for jidu in (q1, q2, q3, q4) )

注意:unpivot没有聚合函数,xiaoshou、jidu字段也是临时的变量

普通方式

create table t4(id int,name varchar2(10),subject varchar2(20),grade number);
insert into t4 values(1,‘ZORRO‘,‘语文‘,70);
insert into t4 values(2,‘ZORRO‘,‘数学‘,80);
insert into t4 values(3,‘ZORRO‘,‘英语‘,75);
insert into t4 values(4,‘SEKER‘,‘语文‘,65);
insert into t4 values(5,‘SEKER‘,‘数学‘,75);
insert into t4 values(6,‘SEKER‘,‘英语‘,60);
insert into t4 values(7,‘BLUES‘,‘语文‘,60);
insert into t4 values(8,‘BLUES‘,‘数学‘,90);
insert into t4 values(9,‘PG‘,‘数学‘,80);
insert into t4 values(10,‘PG‘,‘英语‘,90);
commit; 

SQL> select * from t4; 

ID NAME SUBOBJECT GRADE
---------- ---------- -------------------- ----------
1 ZORRO 语文 70
2 ZORRO 数学 80
3 ZORRO 英语 75
4 SEKER 语文 65
5 SEKER 数学 75
6 SEKER 英语 60
7 BLUES 语文 60
8 BLUES 数学 90
9 PG 数学 80
10 PG 英语 90 

10 rows selected. 

SQL> select name,max(case subobject when ‘语文‘ then grade else 0 end) “语文”,
                 max(case subobject when ‘数学‘ then grade else 0 end) "数学",
                 max(case subobject when ‘英语‘ then grade else 0 end) "英语"
       from t4 group by name; 

----------------------------
| name | 语文 | 数学| 英语|
----------------------------
| zorro | 70 | 80 | 75 |
----------------------------
| seker | 65 | 75 | 60 |
----------------------------
| blues | 60 | 90 | 0 |
----------------------------
| PG | 0 | 80 | 90 |
---------------------------- 

原文地址:https://www.cnblogs.com/marxist/p/12111028.html

时间: 2024-10-11 23:21:15

SQL语句——08、聚集,分组,行转列的相关文章

sql 语句 获取某张表某列字段最短的某几行数据

sql 语句 获取某张表某列字段最短的某几行数据 SELECT C_name,C_code FROM Catalog where LEN(C_code)=LEN((SELECT top 1 C_code FROM Catalog order By LEN(C_code))) 原文地址:https://www.cnblogs.com/woniucode/p/10455406.html

SQL Server之 (四) ADO增删查改 登录demo 带参数的sql语句 插入自动返回行号

SQL Server之 (四) ADO增删查改  登录demo  带参数的sql语句  插入自动返回行号 自己学习笔记,转载请注明出处,谢谢!---酸菜 1.什么是ADO.NET ADO.NET是一组类库,这组类库可以让我们通过程序的方式访问数据库,并以各种方式操作存储在其中的数据; ADO.NET是基于.NET FrameWork,与.NET FrameWork类库的其余部分是高度集成的 2.连接数据库的步骤 ①创建连接字符串 Data Source=XXX-PC; Initial Catal

SQL Server 2008 R2——PIVOT 行转列 以及聚合函数的选择

原文:SQL Server 2008 R2--PIVOT 行转列 以及聚合函数的选择 ==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完整性. 未经作者同意请勿修改(包括本声明),保留法律追究的权利. 未经作者同意请勿用于学术性引用. 未经作者同意请勿用于商业出版.商业印刷.商业引用. 本文不定期修正完善,为保证内容正确,建议移步原文处阅读. 本文

sql语句查询后几行数据并倒着排列

$conn = mysql_connect("数据库地址","用户名","密码"); if(!$conn) { die("mysql conn failed"); } else{ mysql_query("SET NAMES 'utf8'"); mysql_select_db("数据表",$conn); if(!$conn) { die("database selected f

sql server存储过程分页,行变列

CREATE PROCEDURE [dbo].[PROC_GetPriviousAndNextDetailContent]@Index varchar(20),--表主键@Table varchar(100),--从哪个表获取数据@Columns varchar(100),--需要获取哪些字段@OrderStr varchar(100),--排序字段及方式@Where1    varchar(100),--row_number中的初步过滤条件@Where2 varchar(100)--当前要查询

【转】用sql语句创建表的时候给列指定说明(描述)

用sql语句创建表的时候,如何给列指定说明.主要用到sp_addextendedproperty这个存储过程. 语法   sp_addextendedproperty     [ @name = ] { 'property_name' }     [ , [ @value = ] { 'value' }         [ , [ @level0type = ] { 'level0_object_type' }                     , [ @level0name = ] {

微软BI 之SSIS 系列 - 在 SQL 和 SSIS 中实现行转列的 PIVOT 透视操作

开篇介绍 记得笔者在 2006年左右刚开始学习 SQL Server 2000 的时候,遇到一个面试题就是行转列,列转行的操作,当时写了很长时间的 SQL 语句最终还是以失败而告终.后来即使能写出来,也是磕磕碰碰的,虽然很能锻炼 SQL 功底,每次都要挣扎一番,溺水的感觉.记得SQL Server 2005 以后就有了 PIVOT 和 UNPIVOT 这两个函数,可以非常方便的实现行转列和列传行的操作,就不再那么挣扎了.后来,在一个 08 项目中,有一位新的女同事在改一个 ETL,发现 SSIS

Access建表SQL语句Create Table设置自动增长列的关键字AUTOINCREMENT使用方法

SQL AUTO INCREMENT 字段 uto-increment 会在新记录插入表中时生成一个唯一的数字. AUTO INCREMENT 字段 我们通常希望在每次插入新记录时,自动地创建主键字段的值. 我们可以在表中创建一个 auto-increment 字段. 用于 MySQL 的语法 下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键: CREATE TABLE Persons ( P_Id int

SQL Server中使用PIVOT行转列

1.建表及插入数据 1 USE [AdventureDB] 2 GO 3 /****** Object: Table [dbo].[Score] Script Date: 11/25/2016 4:30:50 PM ******/ 4 SET ANSI_NULLS ON 5 GO 6 7 SET QUOTED_IDENTIFIER ON 8 GO 9 10 CREATE TABLE [dbo].[Score]([Name] [varchar](50) NULL,[Subject] [varcha