今天项目测试运行的时候,遇到了一个奇怪的问题,这个问题说起来按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 一对多数据分页查询筛选的更多相关文章

  1. 【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询

    mybatis实现 主从表 left join  1:n 一对多 分页查询   主表从表都有查询条件+count 需求: ======================================= ...

  2. oracle入门之分页查询

    oracle的分页查询共三种方法 1.根据ROWID来分页(速率一般) SQL>select * from emp where rowid in (select rid from (select ...

  3. 【mybatis】在mybatis分页查询时,主表对关联表 一对多 分页查询怎么实现

    现在有这样一个需求: 1.积分商品分页查询 2.一个积分商品会有多张商品图片在商品图片表  1:n的关系 这样在积分商品分页查询的时候,想要顺便把每个积分商品对应的商品图片信息也带出来 实现如下: 1 ...

  4. Oracle三层嵌套分页查询示例及rownum原理

    eg:COMPONENT表数据如下 1.执行select * from (select com.*,rownum  r_num  from (select * from COMPONENT)com w ...

  5. oracle 排序后分页查询

    demo: select * from ( select * from DEV_REG_CFG_CAMERA where 1 = 1 order by unid asc) where rownum & ...

  6. oracle两种分页查询

    第一种: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM table_name) A ) ; 第二种: SELECT * FROM ( ...

  7. Oracle分页查询和SQL server分页查询总结

    分页查询是项目中必不可少的一部分,难倒是不难,就是这些东西,长时间不用,就忘的一干二净了.今天特此总结一下这两款数据库分页查询的实现过程(只记录效率比较高的) 一.Oracle中的分页查询 1.通用分 ...

  8. 分页查询最好加排序(order by)

    昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...

  9. MySQL、Oracle和SQL Server的分页查询语句

    假设当前是第PageNo页,每页有PageSize条记录,现在分别用Mysql.Oracle和SQL Server分页查询student表. 1.Mysql的分页查询: SELECT * FROM s ...

随机推荐

  1. Spring Boot 2 实践记录之 MyBatis 集成的启动时警告信息问题

    按笔者 Spring Boot 2 实践记录之 MySQL + MyBatis 配置 中的方式,如果想正确运行,需要在 Mapper 类上添加 @Mapper 注解. 但是加入此注解之后,启动时会出现 ...

  2. 利用bootstrap上传视频文件,mvc做后台处理

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

  3. 世界线(bzoj2894)(广义后缀自动机)

    由于春希对于第二世代操作的不熟练,所以刚使用完\(invasion process\)便掉落到了世界线之外,错综复杂的平行世界信息涌入到春希的意识中.春希明白了事件的真相. 在一个冬马与雪菜同时存在的 ...

  4. 看linux正在运行的服务用哪个命令?

    https://zhidao.baidu.com/question/117779006.html 查看服务进程:ps aux查看服务cpu利用:top查看服务对应端口:netstat -nlp pst ...

  5. js 从基础入门 到放弃 001

    快速入门  JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html> <head> <s ...

  6. 为autoLayout 增加标识符,方便调试

     如上图,是一个十分简单的布局. root view 上加了一个 button 和一个 webview. 不加标识符的样子 视图层级中没有标识  只有 UIView.WKWebView 之类,如果 ...

  7. POJ 2346

    #include<iostream> #include<stdio.h> using namespace std; ,,,,}; int main() { int num; c ...

  8. Odoo9.0模块开发全流程

    构建Odoo模块 模块组成 业务对象 业务对象声明为Python类, 由Odoo自己主动加载. 数据文件 XML或CSV文件格式, 在当中声明了元数据(视图或工作流).配置数据(模块參数).演示数据等 ...

  9. SAS->关联分析实践

    SAS系统被誉为国际上的标准软件系统,本文将详细介绍如何在SAS/EM模块中进行关联规则数据挖掘,使用的软件版本是SAS 9.1.3下的Enterprise Miner 4.3: 从SAS顶端的[解决 ...

  10. css设置:图片文字等不能被选择

    -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;