转自:https://blog.csdn.net/qq_25237107/article/details/64442969
1.在 MSSQL,oracle 有partition by 的用法

create table score
(
sno varchar(20) ,
cno varchar(20),
degree int
) insert into score (sno ,cno ,degree ) values ('001','a',100)
insert into score (sno ,cno ,degree ) values ('002','a',99)
insert into score (sno ,cno ,degree ) values ('003','a',98)
insert into score (sno ,cno ,degree ) values ('004','a',97)
insert into score (sno ,cno ,degree ) values ('001','b',100)
insert into score (sno ,cno ,degree ) values ('002','b',100)
insert into score (sno ,cno ,degree ) values ('003','b',99)
insert into score (sno ,cno ,degree ) values ('004','b',98)
insert into score (sno ,cno ,degree ) values ('001','c',100)
insert into score (sno ,cno ,degree ) values ('002','c',100)
insert into score (sno ,cno ,degree ) values ('003','c',99)
insert into score (sno ,cno ,degree ) values ('004','c',98) select * from
(
select *,ROW_NUMBER () over(PARTITION BY cno order by degree desc) as pm from score
) x
where x.pm <=3 select * from
(
select *,rank () over(PARTITION BY cno order by degree desc) as pm from score
) x
where x.pm <=3 select * from
(
select *,dense_rank () over(PARTITION BY cno order by degree desc) as pm from score
) x
where x.pm <=3 2.在 mysql中 没有 ROW_NUMBER()over(partition by ... order by ...) 这种写法
需要用其他 替代方法:
方法一:

DROP TABLE IF EXISTS `score`;
 CREATE TABLE `score` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`subject_id` char(10) DEFAULT NULL,
`student_id` char(10) DEFAULT NULL,
`score` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;

INSERT INTO score

select NULL,'1','001',100

UNION
SELECT NULL,'1','002',90
UNION
SELECT null,'1','003',80
UNION
select null,'1','004',99
UNION
select null,'1','005',78
UNION
select null,'1','006',89

UNION
select NULL,'1','001',100
UNION
SELECT NULL,'1','002',90
UNION
SELECT null,'1','003',80
UNION
select null,'1','004',99
UNION
select null,'1','005',78
UNION
select null,'1','006',89

2.

相当于自身全连接:

SELECT AA.*,BB.* FROM score AA JOIN score BB
on AA.subject_id=BB.subject_id AND AA.score>=BB.score
ORDER BY AA.subject_id,AA.score DESC

3. group by 之

SELECT AA.*,BB.* FROM score AA JOIN score BB
on AA.subject_id=BB.subject_id AND AA.score>=BB.score
GROUP BY AA.student_id,AA.subject_id,AA.score
ORDER BY AA.subject_id,AA.score DESC

4.having 之

SELECT AA.id,AA.student_id,AA.subject_id,AA.score FROM score AA JOIN score BB
on AA.subject_id=BB.subject_id AND AA.score>=BB.score

GROUP BY AA.student_id,AA.subject_id,AA.score
HAVING count(AA.subject_id)>=4

ORDER BY AA.subject_id,AA.score DESC

注意: mysql 与 MSsql  之 group by  是不相同的

mysql 使用 group by  后 select 可以 全部字段.  mssql 是不行的

方法二:

Mysql 分组聚合实现 over partition by 功能

转自:https://www.cnblogs.com/zhwbqd/p/4205821.html

https://blog.csdn.net/zzm628/article/details/52181382

mysql中没有类似oracle和postgreSQL的 OVER(PARTITION BY)功能. 那么如何在MYSQL中搞定分组聚合的查询呢

先说结论: 利用 group_concat + substr等函数处理

例如: 订单表一张, 只保留关键字段

id user_id money create_time
1 1 50 1420520000
2 1 100 1420520010
3 2 100 1420520020
4 2 200 1420520030

业务: 查找每个用户的最近一笔消费金额

单纯使用group by user_id, 只能按user_id 将money进行聚合, 是无法将最近一单的金额筛选出来的, 只能满足这些需求, 例如: 每个用户的总消费金额 sum(money), 最大消费金额 max(money), 消费次数count(1) 等

但是我们有一个group_concat可以用, 思路如下:

1. 查找出符合条件的记录, 按user_id asc, create_time desc 排序;

select ord.user_id, ord.money, ord.create_time from orders ord where ord.user_id > 0 and create_time > 0 order by ord.user_id asc , ord.create_time desc
user_id money create_time
1 100 1420520010
1 50 1420520000
2 200 1420520030
2 100 1420520020

2. 将(1)中记录按user_id分组, group_concat(money);

select t.user_id, group_concat( t.money order by t.create_time desc ) moneys from (select ord.user_id, ord.money, ord.create_time from orders ord where ord.user_id > 0 and ord.create_time > 0 order by ord.user_id asc , ord.create_time desc) t group by t.user_id
user_id moneys
1 100,50
2 200,100

3. 这时, 如果用户有多个消费记录, 就会按照时间顺序排列好, 再利用 subString_index 函数进行切分即可

完整SQL, 注意group_concat的内排序, 否则顺序不保证, 拿到的就不一定是第一个了

select t.user_id, substring_index(group_concat( t.money order by t.create_time desc ),',',1) lastest_money from (select ord.user_id, ord.money, ord.create_time from orders ord where ord.user_id > 0 and create_time > 0 order by user_id asc , create_time desc) t group by user_id ; 
user_id moneys
1 100
2 200

利用这个方案, 以下类似业务需求都可以这么做, 如:

1. 查找每个用户过去10个的登陆IP

2. 查找每个班级中总分最高的两个人

补充: 如果是只找出一行记录, 则可以直接只用聚合函数来进行

select t.user_id, t.money  from (select ord.user_id, ord.money, ord.create_time from orders ord where ord.user_id > 0 and create_time > 0 order by user_id asc , create_time desc) t group by user_id ;

前提一定是(1) 只需要一行数据, (2) 子查询中已排好序, (3) mysql关闭 strict-mode

参考资料:

http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sql-mode-strict

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

有任何问题请不吝赐教, 谢谢!


Row_Number() over( PARTITION By cno ...)的更多相关文章

  1. sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据

    SQL Server 2005后之后,引入了row_number()函数,row_number()函数的分组排序功能使这种操作变得非常简单 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系 ...

  2. ROW_NUMBER()与PARTITION BY 实例

    环境:SQL Server 2008 R2 数据表结构 SELECT A.* FROM [tbiz_AssScoreWeidu] A SELECT A.* ,ROW_NUMBER() OVER ( P ...

  3. row_number和partition by分组取top数据

    分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 2005之前,写起来很繁琐,需要用到临时表关联查询才能取到.SQL Serve ...

  4. 去重 ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN

    关键字  ROW_NUMBER() OVER(PARTITION BY 分组字段 ORDER BY 排序字段) RN 按照分组字段进行排序并标编号 ROW_NUMBER() OVER(PARTITIO ...

  5. row_number()over(partition by 字段 order by 字段)ID,修改重复行的字段值。

    案例分析: 现在要查询一个表单里面的运费结果,但是他还有分录,为了显示分录,必须把表头显示出来,问题是,他要查询运费的合计, 但是这样就会导致重复行也加进去了,这样显然数据不准,为此,可以把重复的行设 ...

  6. row_number() OVER(PARTITION BY)函数介绍

      OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个 ...

  7. sqlserver巧用row_number和partition by分组取top数据

    SELECT * FROM( SELECT orderid,createtime, ROW_NUMBER() over(PARTITION by orderid order by createtime ...

  8. SQL技术内幕-4 row_number() over( partition by XX order by XX)的用法(区别于group by 和order by)

    partition by关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指 ...

  9. row_number() OVER (PARTITION BY COL1 ORDER BY COL2)

    select *,ROW_NUMBER() over(partition by deviceID order by RecordDate desc row_number() OVER (PARTITI ...

随机推荐

  1. 爬虫之cookiejar模块

    简介 有时候我们需要爬一些需要登录才能进入网页,这个时候就要用到cookie相关的一些模块来操作了 内置的http包里包含了cookie相关的一些模块,通过她们我们可以自动使用cookie Cooki ...

  2. Spring-ApplicationContext容器

    Spring ApplicationContext容器 ApplicationContext是spring中比较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,并将所有b ...

  3. py-统计一个矩阵中每一列的非0数的个数

    1.文件类型类似于这样: 不过数据量比这个要更大一点. 2.对应上述数据的运行结果: import matplotlib.pyplot as plt with open('test.txt') as ...

  4. 模块讲解----json与pickle模块的区别

    1.在生产中,dumps和loads只进行一次,而且要用w把原来的数据冲掉,从而保证每次都是最新的. 2.虚拟机的快照,是每个快照都有一个文件,而不是全都不放在一起. 3.如果想生产好几个序列化,就生 ...

  5. 小程序页面链接-navigator(导航)

    navigator-页面链接-通过设置open-type的值来确定页面的打开方式. <view class="btn-area"> <navigator url= ...

  6. java poi解析excel日期为数字的问题

    这个数字是什么呢?是以1900年为原点,到2015年8月21日,之间经过的天数. 知道这个后,就很好处理了,我们拿到1900年的日期,在这个日期上加上42237天即可.如下: Calendar cal ...

  7. Andriod实现推送的解决方案(转)

    Andriod上实现消息推送的一般解决策略 第一种解决方案:C2DM云端推送功能 在Android手机平台上,Google提供了C2DM(Cloudto Device Messaging)服务,该服务 ...

  8. (译)Windows Azure的7月更新:SQL数据库,流量管理,自动缩放,虚拟机

    Windows Azure的7月更新:SQL数据库,流量管理,自动缩放,虚拟机 今早我们释出一些很棒的Windows Azure更新.这些新的提升包括:SQL数据库:支持SQL自动导出和一个新的高级层 ...

  9. mongodb中的_id的ObjectId的生成规则

    MongoDB中存储的文档必须有一个"_id" .这个键值可以是任何类型,默认是ObjectID对象.在一个集合里,每个文档都有一个唯一的“_id”,确保集合里的每个文档都能被唯一 ...

  10. 使用IDEA 创建Servlet 的时候,找不到javax.servlet

    使用IDEA 开发工具,创建Servlet 文件的时候,出现了下面的这种错误, 解决步骤如下: 第一步:点击 File 第二步:找到Project Structure,点击,然后按照下图顺序操作,添加 ...