您现在的位置是:网站首页> 编程资料编程资料

分组后分组合计以及总计SQL语句(稍微整理了一下)_MsSql_

2023-05-26 343人已围观

简介 分组后分组合计以及总计SQL语句(稍微整理了一下)_MsSql_

今天看到了这个文章感觉内容挺多的,就是比较乱,实在不好整理,小编就简单整理了一下,希望大家能凑合看吧

分组后分组合计以及总计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/12                        2        2
3        2002/01/01                        3        3
3        2003/12/12                        4        4

按列A分组,请问如何得到每组中时间最大的数据?

1        2001/12/12                        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 where a.new_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 )
--sql2005
select ID,Name,ItemID,Price,CreatedOnfrom (select *,rn=ROW_NUMBER()over(PARTITION by name,ITemID order by price desc) from tb ) kwhere k.rn=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  
  -------------   --------   -------------  
  03106666666 00001 03101111111  
  13711111111 00001 031122222222  
  03108898888 950000  
  031177778777 950000  
  031155955555 00001 031187888876  
   
  注: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.B
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

-六神源码网