oracle 一对多数据分页查询筛选
今天项目测试运行的时候,遇到了一个奇怪的问题,这个问题说起来按sql语法的话是没有错误的
但是呢按照我们的业务来做区分就有些逻辑上的错误了,
下面请听我慢慢道来,在数据库中有两个数据,
先来看下第一次sql是如何写的
查询之后在外面做分页,很正常的逻辑,但是大家都发现了,这是一个多表查询,而且是一对多关系,这就有点问题了
先来看一个图
问题出现在哪呢?
1、需要对主表做分页数据查询, 如:
limit 1,10 或 SELECT * FROM (SELECT A.* ,ROWNUM R FROM (select _ from car) A WHERE ROWNUM <= ${limitEnd} ) B WHERE R >= ${limitStart} ]
以上是对上表做数据统计,然后分页,
2、根据传入字段做筛选,如:车辆的座位数,排量,
出现的问题
因为业务数据庞大,一对多关系数据冗余,出现数据偏移
主要解决思路如下
嗯,下来个图示吧
1、对子表合并,做行转列, 2、在主表做分页筛选时就不会出现,因为一对多关系数据冗余,出现数据偏移
- SELECT * FROM (SELECT A.* ,ROWNUM R FROM (
- select
- T_CAR."ID" as car_ID , T_CAR."CAR_NAME" as car_CAR_NAME , T_CAR."VIN_NUMBER"
- as car_VIN_NUMBER ,car_label.label_ids
- FROM T_CAR
- left join (select CAR_ID,wm_concat(LABLE_ID) as label_ids from T_Car_label group by CAR_ID) car_label on car_label.CAR_ID = T_CAR.ID
- where FIND_IN_SET('4aa06d2b9e904fe8bfeba3505c5dad6a',label_ids)=1
- ) A WHERE ROWNUM <=10 ) B WHERE R >=
FIND_IN_SET:由于写在sql里的筛选很繁琐,此方法是一个储存函数 这个实现不是很好
此函数在mysql下有定义,但是此处因为与业务相关,内部做了一些更改
具体修改是当传进了一个{1,2,3,4}格式的数据时也可以做出条件筛选
- create or replace FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')
- RETURN NUMBER IS
- l_idx_a number:=0; -- 用于计算piv_str1中分隔符的位置
- l_idx_b number:=0; -- 用于计算piv_str2中分隔符的位置
- str_a varchar2(4000); -- 根据分隔符截取的子字符串
- str_b varchar2(4000); -- 根据分隔符截取的子字符串
- piv_str_a varchar2(4000) := piv_str1; -- 将piv_str1赋值给piv_str_a
- piv_str_b varchar2(4000) := piv_str2; -- 将piv_str2赋值给piv_str_b
- res number:=0; -- 返回结果
- BEGIN
- -- 如果piv_str_a中没有分割符,直接循环判断piv_str_a和piv_str_b是否相等,相等 res=1
- IF instr(piv_str_a, p_sep, 1) = 0 THEN
- -- 如果piv_str2中没有分割符,直接判断piv_str1和piv_str2是否相等,相等 res=1
- IF instr(piv_str_b, p_sep, 1) = 0 THEN
- IF piv_str_a = piv_str_b THEN
- res:= 1;
- END IF;
- ELSE
- -- 循环按分隔符截取piv_str_b
- LOOP
- l_idx_b := instr(piv_str_b,p_sep);
- -- 当piv_str中还有分隔符时
- IF l_idx_b > 0 THEN
- -- 截取第一个分隔符前的字段str
- str_a:= substr(piv_str_b,1,l_idx_b-1);
- -- 判断 str 和piv_str_a 是否相等,相等 res=1 并结束循环判断
- IF str_a = piv_str_a THEN
- res:= 1;
- EXIT;
- END IF;
- piv_str_b := substr(piv_str_b,l_idx_b+length(p_sep));
- ELSE
- -- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=1
- IF piv_str_a = piv_str_b THEN
- res:= 1;
- END IF;
- -- 无论最后是否相等,都跳出循环
- EXIT;
- END IF;
- END LOOP;
- -- 结束循环
- END IF;
- ELSE
- -- 循环按分隔符截取piv_str_a
- LOOP
- l_idx_a := instr(piv_str_a,p_sep);
- -- 当piv_str_a中还有分隔符时
- IF l_idx_a > 0 THEN
- -- 截取第一个分隔符前的字段str
- str_a:= substr(piv_str_a,1,l_idx_a-1);
- -- 如果piv_str_b中没有分割符,直接判断piv_str1和piv_str是否相等,相等 res=1
- IF instr(piv_str_b, p_sep, 1) = 0 THEN
- -- 判断 str_a 和piv_str_b 是否相等,相等 res=1 并结束循环判断
- IF str_a = piv_str_b THEN
- res:= 1;
- EXIT;
- END IF;
- ELSE
- -- 循环按分隔符截取piv_str_b
- LOOP
- l_idx_b := instr(piv_str_b,p_sep);
- -- 当piv_str中还有分隔符时
- IF l_idx_b > 0 THEN
- -- 截取第一个分隔符前的字段str
- str_b:= substr(piv_str_b,1,l_idx_b-1);
- -- 判断 str 和piv_str1 是否相等,相等 res=1 并结束循环判断
- IF str_b = str_a THEN
- res:= 1;
- EXIT;
- END IF;
- piv_str_b := substr(piv_str_b,l_idx_b+length(p_sep));
- ELSE
- -- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=1
- IF piv_str_a = piv_str_b THEN
- res:= 1;
- END IF;
- -- 无论最后是否相等,都跳出循环
- EXIT;
- END IF;
- END LOOP;
- -- 结束循环
- END IF;
- piv_str_a := substr(piv_str_a,l_idx_a+length(p_sep));
- ELSE
- -- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=1
- IF piv_str_a = piv_str_b THEN
- res:= 1;
- END IF;
- -- 无论最后是否相等,都跳出循环
- EXIT;
- END IF;
- END LOOP;
- -- 结束循环
- END IF;
- -- 返回res
- RETURN res;
- END FIND_IN_SET;
然后完美解决
oracle 一对多数据分页查询筛选的更多相关文章
- 【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询
mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件+count 需求: ======================================= ...
- oracle入门之分页查询
oracle的分页查询共三种方法 1.根据ROWID来分页(速率一般) SQL>select * from emp where rowid in (select rid from (select ...
- 【mybatis】在mybatis分页查询时,主表对关联表 一对多 分页查询怎么实现
现在有这样一个需求: 1.积分商品分页查询 2.一个积分商品会有多张商品图片在商品图片表 1:n的关系 这样在积分商品分页查询的时候,想要顺便把每个积分商品对应的商品图片信息也带出来 实现如下: 1 ...
- Oracle三层嵌套分页查询示例及rownum原理
eg:COMPONENT表数据如下 1.执行select * from (select com.*,rownum r_num from (select * from COMPONENT)com w ...
- oracle 排序后分页查询
demo: select * from ( select * from DEV_REG_CFG_CAMERA where 1 = 1 order by unid asc) where rownum & ...
- oracle两种分页查询
第一种: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM table_name) A ) ; 第二种: SELECT * FROM ( ...
- Oracle分页查询和SQL server分页查询总结
分页查询是项目中必不可少的一部分,难倒是不难,就是这些东西,长时间不用,就忘的一干二净了.今天特此总结一下这两款数据库分页查询的实现过程(只记录效率比较高的) 一.Oracle中的分页查询 1.通用分 ...
- 分页查询最好加排序(order by)
昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...
- MySQL、Oracle和SQL Server的分页查询语句
假设当前是第PageNo页,每页有PageSize条记录,现在分别用Mysql.Oracle和SQL Server分页查询student表. 1.Mysql的分页查询: SELECT * FROM s ...
随机推荐
- Code Review Checklist and Guidelines for C# Developers
Checklist1. Make sure that there shouldn't be any project warnings.2. It will be much better if Code ...
- Jesery客户端工具类
public class JerseyClientUtil { public static<T> T sendMsg(String url,Object object,Class<T ...
- [JS] 数据双向绑定原理
通常在前端开发过程中,经常遇到需要绑定两个甚至多个元素之间的值,比如将input的值绑定到一个h1上,改变input的值,h1的文字也自动更新. <h1 id="title" ...
- Global.asax和HttpModule的执行顺序
Application_Start-->用户自定义的HttpModule-->Application_BeginRequest (注册->调用) 看到Init方法(在用户自定义的 ...
- ASP.NET Core 2 学习笔记(三)中间件
之前ASP.NET中使用的HTTP Modules及HTTP Handlers,在ASP.NET Core中已不复存在,取而代之的是Middleware.Middleware除了简化了HTTP Mod ...
- mvc基础知识(1)
复制大佬的,侵权请联系我主动删除 1.js/css合并 在之前的crud例子中,我们引入js/css脚本的方式和平常的web开发一样 <script src="~/Scripts/jq ...
- With语句上下文管理
在平时工作中总会有这样的任务,它们需要开始前做准备,然后做任务,然后收尾清理....比如读取文件,需要先打开,读取,关闭 这个时候就可以使用with简化代码,很方便 1.没有用with语句 1 2 3 ...
- Django + DRF + Elasticsearch 实现搜索功能
django使用haystack来调用Elasticsearch搜索引擎 如何使用django来调用Elasticsearch实现全文的搜索 Haystack为Django提供了模块化的搜索.它的特 ...
- jzoj4424
20%:暴力枚舉每一條邊有沒有被選到,然後使用并查集判斷聯通性 這樣子有20分,但是我考試寫掛了所以1分也沒有 100%:這道題2000的數據範圍,使用指數級搜索會tle,需要更加好的方法 這道題中, ...
- docker容器的基本操作
docker容器是独立运行的一个或一组应用,以及它们的运行态环境.下面具体介绍如何管理一个容器,包括容器的创建,启动和停止等. 启动容器 基于镜像新建一个容器并启动 将终止状态的容器重新启动 新建并启 ...