本文共 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/