博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Sql 语句小课堂2:获取指定记录相邻的记录
阅读量:4162 次
发布时间:2019-05-26

本文共 4762 字,大约阅读时间需要 15 分钟。

需求描述1:获取指定文章的上一篇和下一篇的标题

需求描述2:获得指定用户某次操作的前后各5次操作记录

需求描述3:获得指定产品的特定销售记录,并向前向后各附加最近的3次销售记录,如前后数量不足,则逆向补足

首先,我们可以看到,这些都是记录的前后补足式的需求,但是这些记录的输出未必是按照自增字段进行排序的,即便是按照自增字段排序,但也可能因为物理删除,造成ID的不连续情况,所以我们使用一个开窗函数 row_number 来进行追加一个字段,用来生成连续自然数,然后按照这个连续自然数进行数据获取

先看一个示例简单了解下row_number

select *,row_number() over(order by type,number) as n from master..spt_valuesselect * from (select *,row_number() over(partition by type order by type,number) as n from master..spt_values) a order by n,type

通过row_number,我们可以得到连续自然数,那么需求1就很容易解决了,即获取n为当前记录的+1和-1的记录即可

下边为示例所用数据集

select id,pub_time,row_number() over(order by pub_time) as rid from pub_articles with (nolock) where art_online=1 and art_delete=0 and convert(date,pub_time)='2019-9-17' ----id          pub_time                rid----------- ----------------------- --------------------326268      2019-09-17 08:59:26.000 1326269      2019-09-17 09:11:03.000 2326271      2019-09-17 09:12:58.000 3326272      2019-09-17 09:14:30.000 4326273      2019-09-17 09:16:18.000 5326274      2019-09-17 09:17:11.000 6326270      2019-09-17 09:17:25.000 7326275      2019-09-17 09:20:06.000 8326276      2019-09-17 09:21:55.000 9326277      2019-09-17 09:31:02.000 10326278      2019-09-17 09:45:44.000 11326279      2019-09-17 10:09:31.000 12326280      2019-09-17 10:11:01.000 13326281      2019-09-17 10:12:17.000 14326282      2019-09-17 10:12:50.000 15326283      2019-09-17 10:13:48.000 16326285      2019-09-17 10:56:35.000 17326286      2019-09-17 11:04:22.000 18326287      2019-09-17 11:06:09.000 19326284      2019-09-17 11:08:34.000 20326288      2019-09-17 11:18:09.000 21326289      2019-09-17 11:40:34.000 22326290      2019-09-17 11:50:17.000 23326291      2019-09-17 13:00:36.000 24326292      2019-09-17 13:24:26.000 25326293      2019-09-17 13:24:54.000 26326294      2019-09-17 13:25:05.000 27326295      2019-09-17 13:25:14.000 28326296      2019-09-17 13:25:28.000 29326297      2019-09-17 13:26:58.000 30326298      2019-09-17 13:35:58.000 31326299      2019-09-17 13:55:02.000 32326300      2019-09-17 14:09:33.000 33326301      2019-09-17 14:28:04.000 34326304      2019-09-17 15:11:35.000 35326302      2019-09-17 15:13:14.000 36326303      2019-09-17 15:14:08.000 37326305      2019-09-17 15:37:20.000 38326306      2019-09-17 15:51:58.000 39326307      2019-09-17 15:53:23.000 40326309      2019-09-17 16:21:08.000 41326312      2019-09-17 16:38:30.000 42326313      2019-09-17 16:42:07.000 43326314      2019-09-17 16:48:59.000 44326315      2019-09-17 16:52:59.000 45326311      2019-09-17 16:57:06.000 46326316      2019-09-17 17:23:45.000 47326317      2019-09-17 17:30:38.000 48(48 行受影响)

可以看到,ID并不是连续的,但是用row_number得到的rid是连续的

现在,我们来获取id为326275的文章及其前后文章的id吧

with t as (	select id,pub_time,row_number() over(order by pub_time) as rid 	from pub_articles with (nolock) 	where art_online=1 and art_delete=0 and convert(date,pub_time)='2019-9-17' )select * from t where rid between (select rid-1 from t where id=326275) and (select rid+1 from t where id=326275)order by ridid          pub_time                rid----------- ----------------------- --------------------326270      2019-09-17 09:17:25.000 7326275      2019-09-17 09:20:06.000 8326276      2019-09-17 09:21:55.000 9(3 行受影响)

需求2也仅仅是rid-5和rid+5的改变

需求3的话,则多了一个需要进行数据补足的操作,例如id为326272,则返回326268,326269,326271,326272,326273,326274,326270,前后各追加3个,如果不足,例如326268,那么返回的结果也是这7条,那就需要进行rid的between范围计算了,但是在帖子里,2楼给出了一个新的思路,我们直接按照rid进行分组,当rid小于指定id的rid和rid大于指定id的rid,然后小于的rid*2,大于的rid*2+1,然后按照新的这个结果排序取top。。。Hmmmm好主意

with t as (	select id,pub_time,row_number() over(order by pub_time) as rid 	from pub_articles with (nolock) 	where art_online=1 and art_delete=0 and convert(date,pub_time)='2019-9-17' ),t1 as (	select * from t where id=326271),t2 as (	select *,rid-(select rid from t1) as nid 	from t),t3 as (	select *,row_number() over(order by abs(nid),nid) as rowid from t2)select * from t3 where rowid between 1 and 7order by nidid          pub_time                rid                  nid                  rowid----------- ----------------------- -------------------- -------------------- --------------------326268      2019-09-17 08:59:26.000 1                    -2                   4326269      2019-09-17 09:11:03.000 2                    -1                   2326271      2019-09-17 09:12:58.000 3                    0                    1326272      2019-09-17 09:14:30.000 4                    1                    3326273      2019-09-17 09:16:18.000 5                    2                    5326274      2019-09-17 09:17:11.000 6                    3                    6326270      2019-09-17 09:17:25.000 7                    4                    7(7 行受影响)

这次我选择使用326271作为指定id,得到的结果如上,这样就完成了需求3

至于最后的输出,直接用这个结果集inner join 原来的文章表即可,这样排序和字段就都可以弄好了

转载地址:http://txvxi.baihongyu.com/

你可能感兴趣的文章
数学等于号是=那三个横杠是什么符
查看>>
HTTP协议详解
查看>>
java多线程中的join方法详解
查看>>
java abstract修饰符
查看>>
数组分为两部分,使得其和相差最小
查看>>
有趣的排序——百度2017春招
查看>>
二叉树的最近公共祖先LCA
查看>>
数组中累加和为定值K的最长子数组长度
查看>>
素数对--腾讯2017校招编程
查看>>
JAVA集合--ArrayList实现原理
查看>>
synchronized与Lock
查看>>
数据库索引
查看>>
实现包含min,max,push,pop函数的栈
查看>>
实验2-6 字符型数据的输入输出
查看>>
实验3-5 编程初步
查看>>
实验4-1 逻辑量的编码和关系操作符
查看>>
实验5-2 for循环结构
查看>>
实验5-3 break语句和continue语句
查看>>
实验5-4 循环的嵌套
查看>>
实验5-5 循环的合并
查看>>