查看: 891|回复: 12

[SQL] 表中一个字段有大小不等的数值,怎么取出所有小于前n个数,也小于后n个数值的数(n...

[复制链接]
论坛徽章:
3
2013年新春福章
日期:2013-02-25 11:02:122013年新春福章
日期:2013-02-25 14:51:24茶鸡蛋
日期:2013-07-01 10:57:47
发表于 2018-4-28 09:59 | 显示全部楼层 |阅读模式
表中一个字段有大小不等的数值,怎么取出所有小于前n个数,也小于后n个数值的数(n可以是1也可以是10)?举个例
5
3
1
7
6
3
8
9

这里小于前2个数,也小于后两个数的数是 1和3.
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-4-28 11:57 | 显示全部楼层
表中的数据是无序的,你必须现有一个排序方法,才能定义出所谓的前N个后N个。没有ORDER BY得到的顺序都是随机结果。
你还得说清楚重复的数据要怎么处理,除非你的所有数据都是唯一的。
参见置顶帖提问的智慧。

使用道具 举报

回复
论坛徽章:
3
2013年新春福章
日期:2013-02-25 11:02:122013年新春福章
日期:2013-02-25 14:51:24茶鸡蛋
日期:2013-07-01 10:57:47
 楼主| 发表于 2018-5-3 16:25 | 显示全部楼层
newkid 发表于 2018-4-28 11:57
表中的数据是无序的,你必须现有一个排序方法,才能定义出所谓的前N个后N个。没有ORDER BY得到的顺序都是随 ...

当然有个id列是有序的

使用道具 举报

回复
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-5-3 17:57 | 显示全部楼层

使用道具 举报

回复
认证徽章
论坛徽章:
1
秀才
日期:2016-04-21 14:08:53
发表于 2018-5-3 18:44 | 显示全部楼层
蠢办法来抛砖引玉,这个sql实质上是求出前N行和后N行之中的最小值,然后取出<=该最小值的即可:
--创建测试表
create table test(no number,id number);

--插入测试数据
Insert into  TEST
   (id, no)
Values
   (1, 5);
Insert into  TEST
   (id, no)
Values
   (2, 3);
Insert into  TEST
   (id, no)
Values
   (3, 1);
Insert into  TEST
   (id, no)
Values
   (4, 7);
Insert into  TEST
   (id, no)
Values
   (5, 6);
Insert into  TEST
   (id, no)
Values
   (6, 3);
Insert into  TEST
   (id, no)
Values
   (7, 8);
Insert into  TEST
   (id, no)
Values
   (8, 9);
COMMIT;

--以n=2为例,取<=前2行和<=后2行的交集,结果得到1,3
select no from test where no<=(
select min(no) from (
select no from test order by id asc
) where rownum<=2)
intersect
select no from test where no<=(
select min(no) from (
select no from test order by id desc
) where rownum<=2)

使用道具 举报

回复
论坛徽章:
400
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2018-5-3 19:28 来自手机 | 显示全部楼层
3<3?

使用道具 举报

回复
论坛徽章:
400
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2018-5-3 19:30 来自手机 | 显示全部楼层
大小不等就是不重复?怎么有2个3

使用道具 举报

回复
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-5-4 15:17 | 显示全部楼层
Dimsen 发表于 2018-5-3 18:44
蠢办法来抛砖引玉,这个sql实质上是求出前N行和后N行之中的最小值,然后取出

思路是对的,但是SQL是错的。你的标量子查询和外层没有相关条件,不能限制范围在前后N个。

使用道具 举报

回复
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-5-4 15:18 | 显示全部楼层
〇〇 发表于 2018-5-3 19:30
大小不等就是不重复?怎么有2个3

我在2楼已经问过重复的问题,楼主很跩地没有理会。

使用道具 举报

回复
论坛徽章:
0
发表于 2018-5-15 15:24 | 显示全部楼层
猜测楼主意思:按照id排序,该表的num字段值 小于id排序后前两个的num字段值&&小于id排序后后两个的num字段值。
        --1、建表
create table mytab(
my_id varchar2(10),
my_num number(10)
);
        --2、数据不多,直接forupdate手工写入
select * from mytab for update;
        --3、查询语句
select m.*
  from mytab m
where exists (select 1
          from (select t.my_id,
                       t.my_num,
                       row_number() over(partition by 1 order by t.my_id asc) row_num
                  from mytab t) tb
         where tb.row_num = 2
           and m.my_num < tb.my_num)
   and exists (select 1
          from (select t.my_id,
                       t.my_num,
                       row_number() over(partition by 1 order by t.my_id desc) row_num
                  from mytab t) bm
         where bm.row_num = 2
           and m.my_num < bm.my_num);

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 虎吧 老博客 知识索引树 读书频道 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表