分组后分组合计以及总计SQL语句(稍微整理了⼀下)
今天看到了这个⽂章感觉内容挺多的,就是⽐较乱,实在不好整理,⼩编就简单整理了⼀下,希望⼤家能凑合看吧
分组后分组合计以及总计SQL语句
1)想⼀次性得到分组合计以及总计,sql:
SELECT 分组字段 FROM 表
GROUP BY 分组字段
compute sum(COUNT(*))
2)分组合计1:
SELECT COUNT(*)
FROM (SELECT 分组字段 FROM 表
GROUP BY 分组字段
)别名
3)分组合计2:
SELECT COUNT(*)
FROM (SELECT distinct 分组字段 FROM 表)别名
4)统计分组后的种类数:
例⼦1:分组合计
SELECT JSSKQK_JGH FROM SJ_JSSKQK WHERE JSSKQK_JGH IN (SELECT JSJBXX_JGH FROM SJ_JSJBXX WHERE JSJBXX_JSLXM1=1) GROUP BY JSSKQK_JGH HAVING ((SUM(JSSKQK_SSKCXS1) /40)>5) 上⾯的语句已经可以满⾜要求分组了.假设执⾏后有3条记录,怎么才能把这个COUNT值求出?
select count(*) from
(
SELECT JSSKQK_JGH
FROM SJ_JSSKQK
WHERE JSSKQK_JGH IN (SELECT JSJBXX_JGH FROM SJ_JSJBXX WHERE JSJBXX_JSLXM1=1)
GROUP BY JSSKQK_JGH HAVING ((SUM(JSSKQK_SSKCXS1) /40)>5)
) t
例⼦2:[PL/SQL] 如何得到分组后,组中最⼤⽇期的纪录
TABLE:A
A        B                C        D
1        2001/01/01                        1        1
1        2001/12/1
2                        2        2
3        2002/01/01                        3        3
3        2003/12/12
4        4
按列A分组,请问如何得到每组中时间最⼤的数据?
1        2001/12/1
2                        2        2
3        2003/12/12
4        4
我的笨⽅法:
SELECT *
FROM A
WHERE (A,B) IN(
SELECT A,MAX(B)
FROM A
GROUP BY A
)
有更好的⽅法吗?
1,select * from a out
where b = (select max(b) from a in
where in.a = out.a)
2,Select * from
(select a, row_number() over (partition by a
order by b desc) rn
from a)
where rn=1
3,Select a, b,c,d from
(select a, b,c,d,row_number() over (partition by a
order by b desc) rn
from a)
where rn=1
4,select A,B,C,D from test
where rowid in
(
select rd from
(
select rowid rd ,rank() over(partion A order by B desc)rk from test
) where rk=1
)
)
例⼦3:SQL语句分组获取记录的第⼀条数据的⽅法
使⽤Northwind 数据库
⾸先查询Employees表
查询结果:
city列⾥⾯只有5个城市
使⽤ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2) 先进⾏分组注:根据COL1分组,在分组内部根据 COL2排序,⽽此函数计算的值就表⽰每组内部排序后的顺序编号(组内连续的唯⼀的).
sql语句为:
select EmployeeID,LastName,FirstName,Title,TitleOfCourtesy,City,ROW_NUMBER() over(partition by City order by EmployeeID) as new_index
from Employees
执⾏结果图:
可以看到是按照City分组,EmployeeID排序。
select出分组中的第⼀条记录
执⾏语句:
select * from
(select EmployeeID,LastName,FirstName,Title,TitleOfCourtesy,City,ROW_NUMBER() over(partition by City order by EmployeeID) as new_index
from Employees) a w_index=1
执⾏结果图:
例⼦4:sql 获取分组结果后,如何每⼀组的第⼀条记录
Eric  red  20
eric  blue  30
andy red  10
andy  blue  5
例如,只获取⿊体的记录。
1,declare @fTable table (fName varchar(10), fColor varchar(10), fOrder int)
insert into @fTable values('Eric', 'red', 20)
insert into @fTable values('eric', 'blue', 30)
insert into @fTable values('andy', 'red', 10)
insert into @fTable values('andy', 'blue', 5)
-- 只获取红⾊
select * from @fTable where fColor = 'red'
-- 每个 fColor 取⼀条记录(按 fOrder 正序)
select * from @fTable A where fName = (select top 1 fName from @fTable where fColor = A.fColor order by fOrder )
-- 每个 fColor 取⼀条记录(按 fOrder 反序)
select * from @fTable A where fName = (select top 1 fName from @fTable where fColor = A.fColor order by fOrder desc)
2,SQL2005以上版本
select * from (select *,row=row_number()over(partition by Color order by Color) from table1)t where row=1 and color='xx'--加上件
SQL2000⽤ top 1
例⼦5:⼀条SQL语句搞定分组并且每组限定记录集的数量
如果我想得到这样⼀个结果集:分组,并且每组限定记录集的数量,⽤⼀条SQL语句能办到吗?
⽐如说,我想出学⽣期末考试中,每科的前3名,只⽤⼀条SQL语句,该怎么写?
表[TScore]的结构
code      学号 char
subject  科⽬ int
score    成绩 int
可以这样写:
SELECT [code]
,[subject]
,[score]
FROM (
SELECT *
,RANK() OVER(PARTITION BY subject ORDER BY score DESC) AS Row
FROM TScore
) AS a
WHERE Row <= 3 ;
例⼦6:SQL获取每个分组的第⼀条记录
SQL查询以下伪数据获取粗体字⾏的记录
ID,Name,ItemID,Price,CreatedOn
1 a 1 10.00 xxx1
2 a 1 12.00 xxx2
3 b 1 9.00 xxx1
4 b 1 11.50 xxx2
5 c 1 20.00 xxx1
6 a 2 21.00 xxx1
7 a 2 23.00 xxx2
8 b 2 35.00 xxx1
9 c 2 31.00 xxx1
10 c 2 30.50 xxx2
获取每个分组中的第⼀条记录,当ItemID有多条记录时,选取Price最⾼的
--sql2000
select *
from tbname k
where not exists(select * from tbname where
name=k.name and ITemID=K.ITemID and k.price<price
)
--sql2005
select ID,Name,ItemID,Price,CreatedOnfrom (select *,rn=ROW_NUMBER()over(PARTITION by name,ITemID order by price desc) from tb ) =1
例⼦7:分组后取第⼀条记录的SQL语句
分享
有如下表结构:
字段      A,      B,      C
值为      a1,    b1,    c1
a2,    b2,    c2
a2,    b3,    c3
a3,    b4,    c4
a3,    b5,    c5
想要得到的结果集以A字段为分组条件,并取出每⼀个分组中的第⼀条记录,如下:
A,      B,      C
值为      a1,    b1,    c1      --a1分组的第⼀条记录。
a2,    b2,    c2      --a2分组的第⼀条记录。
a3,    b4,    c4      --a3分组的第⼀条记录。
select  *  from  表  tem  where  c=(select  top  1  c  from  表  where  a=tem.a)
现有数据表call如下:
zj                              th                  bj
-------------  --------  -------------
0310******* 00001 0310*******
137******** 00001 0311********
0310******* 950000
0311******** 950000
0311******** 00001 0311********
注:th如为950000,则bj为空,th如为00001,则bj不是空。
1、bj分组
select  substr(bj,1,4)  as  区号,count(*)  as  呼叫总量  from  call
group  by  substr(bj,1,4);
执⾏结果
区号呼叫总量
------------    --------------
0310                          1
0311                          2
2
2、zj分组,条件是th为950000的记录
select  substr(zj,1,4)  as  区号,count(*)  as  呼叫总量  from  call
where  th=950000
group  by  substr(zj,1,4);
执⾏结果:
区号呼叫总量
------------    --------------
0310                          1
0311                          1
能否有⼀个语句就能实现如下结果:
区号呼叫总量
-
-----------    --------------
0310                          2
0311                          3
注:想要得到结果是1对应的⾏加2对应的⾏。
union起来再求和
select  区号,sum(呼叫总量)  from
(select  substr(bj,1,4)  as  区号,count(*)  as  呼叫总量  from  call
group  by  substr(bj,1,4))
union  all
(select  substr(zj,1,4)  as  区号,count(*)  as  呼叫总量  from  call
where  th=950000
group  by  substr(zj,1,4))
group  by  区号;
这个应该在Oracle中运⾏
select
decode(th,'950000',substr(zj,1,4),substr(bj,1,4))  as  区号,
count(*)  as  呼叫总量
from
call
group  by
decode(th'950000',substr(zj,1,4),substr(bj,1,4))
decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)
该函数的含义如下:
IF 条件=值1 THEN
    RETURN(翻译值1)
ELSIF 条件=值2 THEN
    RETURN(翻译值2)
    ......
ELSIF 条件=值n THEN
    RETURN(翻译值n)
ELSE
    RETURN(缺省值)
END IF
例⼦8:在SQL Server2005/2008中对记录进⾏分组,并获得每组前N条记录
假设有⼀个表,SQL语句如下:
CREATE TABLE [dbo].[scan](
[km] [int] NULL,
[kh] [int] NULL,
[cj] [int] NULL
) ON [PRIMARY]
其中km为科⽬号、kh为考⽣号、cj为成绩,现对km和kh进⾏分组,并获得每组前2条记录(按cj从⾼到低排序)。基本思想是为每组加⼀个序号列,再⽤where取序号⼩于等于2的。SQL语句如下:
select * from
(
select a.km,a.kh,cj,row_number() over(partition by a.km order by a.km,a.cj desc) n
from
(select km,kh,SUM(cj) cj from scan group by km,kh) a
) b where n<=2  order by km, cj desc
最后得到的结果集如下图所⽰。
例⼦9:如何实现分组Group取前N条记录的sql语句
在表A中根据字段B分组、根据字段C排序并查询出每组中的前三条记录,查询结果要求包含所有字段,请问sql语句该怎么写?下⾯的sql语句虽然可以实现,但由于数据量⽐较⼤,耗费时间太长,有没有不通过表联接⽽直接分组取记录的⽅法呢?多谢!
select *
from 表A as t1
where 主键 in(
select top 3 主键
from 表A as t2
where t1.B=t2.Bsql语句查询不包含
order by t2.C)
注释  (隐藏注释)
答案1
作者:邹建
select id=identity(int,1,1),b, 主键 into # from 表A order by B,C
select a.*
from 表A a, # b,(select id1=min(id),id2=min(id)+2 from # group by b)c
where a.主键=b.主键
and b.id between c.id1 and c.id2
drop table #
答案2
作者:aierong
求每组前2名,你有⼏种⽅法?(MS SQL2000)
create table abc(
i nvarchar(10),
ii int,
iii int,
iiii int,
price money)
Go
insert into abc
select 'b',1,2,1,11
union all
select 'b',211,2,1,211
union all
select 'a',21,2,1,311
union all
select 'd',41,42,1,411
union all
select 'd',41,42,1,511
union all
select 'd',41,42,1,611
union all
select 'e',1,2,1,11
union all
select 'e',71,2,1,31
union all
select 'e',61,2,1,911
union all
select 'e',771,2,1,1
go
要求的结果是:
以i分组,求每组price最⼤的前2条记录
i ii iii iiii price
---------- ----------- ----------- ----------- ---------------------
a 21 2 1 311.0000
b 1 2 1 11.0000
b 211 2 1 211.0000
d 41 42 1 511.0000
d 41 42 1 611.0000
e 71 2 1 31.0000
e 61 2 1 911.0000
连接查询,判断数量
2.
select i,ii,iii,iiii,price
from (
select (select isnull(sum(1),0)+1 from abc b where a.i=b.i and a.price<b.price) ids,* from abc a) tem
where ids<3
order by i,price
⽣产⼀个内部表,给内部表tem中的每⼀组排序,并把排序号放⼊新列ids中
3.
declare @looptime int
declare @count int
declare @i nvarchar(10)
/定义表变量@abc,和表ABC中的所有列类型相同/
declare @abc table(
i nvarchar(10),
ii int,
iii int,
iiii int,
price money)
declare @tem table(
ids int identity,
class nvarchar(10))
/把表ABC中的所有组全部查询出来,暂时存在表变量@tem中/
insert into @tem(class)
select i
from abc
group by i
/求出表变量@tem中⾏数量/
select @count=@@rowcount
/循环变量@looptime赋初值=1/
select @looptime=1
while(@looptime<=@count)
begin
/将每组名赋值到变量@i/
select @i=class

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。