今天项目测试运行的时候,遇到了一个奇怪的问题,这个问题说起来按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、在主表做分页筛选时就不会出现,因为一对多关系数据冗余,出现数据偏移

  1. SELECT * FROM (SELECT A.* ,ROWNUM R FROM (
  2.  
  3. select
  4. T_CAR."ID" as car_ID , T_CAR."CAR_NAME" as car_CAR_NAME , T_CAR."VIN_NUMBER"
  5. as car_VIN_NUMBER ,car_label.label_ids
  6. FROM T_CAR
  7. 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
  8. where FIND_IN_SET('4aa06d2b9e904fe8bfeba3505c5dad6a',label_ids)=1
  9. ) A WHERE ROWNUM <=10 ) B WHERE R >=

FIND_IN_SET:由于写在sql里的筛选很繁琐,此方法是一个储存函数 这个实现不是很好

此函数在mysql下有定义,但是此处因为与业务相关,内部做了一些更改

具体修改是当传进了一个{1,2,3,4}格式的数据时也可以做出条件筛选

  1. create or replace FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')
  2. RETURN NUMBER IS
  3. l_idx_a number:=0; -- 用于计算piv_str1中分隔符的位置
  4. l_idx_b number:=0; -- 用于计算piv_str2中分隔符的位置
  5. str_a varchar2(4000); -- 根据分隔符截取的子字符串
  6. str_b varchar2(4000); -- 根据分隔符截取的子字符串
  7. piv_str_a varchar2(4000) := piv_str1; -- piv_str1赋值给piv_str_a
  8. piv_str_b varchar2(4000) := piv_str2; -- piv_str2赋值给piv_str_b
  9. res number:=0; -- 返回结果
  10. BEGIN
  11. -- 如果piv_str_a中没有分割符,直接循环判断piv_str_apiv_str_b是否相等,相等 res=1
  12. IF instr(piv_str_a, p_sep, 1) = 0 THEN
  13. -- 如果piv_str2中没有分割符,直接判断piv_str1piv_str2是否相等,相等 res=1
  14. IF instr(piv_str_b, p_sep, 1) = 0 THEN
  15. IF piv_str_a = piv_str_b THEN
  16. res:= 1;
  17. END IF;
  18. ELSE
  19. -- 循环按分隔符截取piv_str_b
  20. LOOP
  21. l_idx_b := instr(piv_str_b,p_sep);
  22. -- piv_str中还有分隔符时
  23. IF l_idx_b > 0 THEN
  24. -- 截取第一个分隔符前的字段str
  25. str_a:= substr(piv_str_b,1,l_idx_b-1);
  26. -- 判断 str piv_str_a 是否相等,相等 res=1 并结束循环判断
  27. IF str_a = piv_str_a THEN
  28. res:= 1;
  29. EXIT;
  30. END IF;
  31. piv_str_b := substr(piv_str_b,l_idx_b+length(p_sep));
  32. ELSE
  33. -- 当截取后的piv_str 中不存在分割符时,判断piv_strpiv_str1是否相等,相等 res=1
  34. IF piv_str_a = piv_str_b THEN
  35. res:= 1;
  36. END IF;
  37. -- 无论最后是否相等,都跳出循环
  38. EXIT;
  39. END IF;
  40. END LOOP;
  41. -- 结束循环
  42. END IF;
  43. ELSE
  44. -- 循环按分隔符截取piv_str_a
  45. LOOP
  46. l_idx_a := instr(piv_str_a,p_sep);
  47. -- piv_str_a中还有分隔符时
  48. IF l_idx_a > 0 THEN
  49. -- 截取第一个分隔符前的字段str
  50. str_a:= substr(piv_str_a,1,l_idx_a-1);
  51. -- 如果piv_str_b中没有分割符,直接判断piv_str1piv_str是否相等,相等 res=1
  52. IF instr(piv_str_b, p_sep, 1) = 0 THEN
  53. -- 判断 str_a piv_str_b 是否相等,相等 res=1 并结束循环判断
  54. IF str_a = piv_str_b THEN
  55. res:= 1;
  56. EXIT;
  57. END IF;
  58. ELSE
  59. -- 循环按分隔符截取piv_str_b
  60. LOOP
  61. l_idx_b := instr(piv_str_b,p_sep);
  62. -- piv_str中还有分隔符时
  63. IF l_idx_b > 0 THEN
  64. -- 截取第一个分隔符前的字段str
  65. str_b:= substr(piv_str_b,1,l_idx_b-1);
  66. -- 判断 str piv_str1 是否相等,相等 res=1 并结束循环判断
  67. IF str_b = str_a THEN
  68. res:= 1;
  69. EXIT;
  70. END IF;
  71. piv_str_b := substr(piv_str_b,l_idx_b+length(p_sep));
  72. ELSE
  73. -- 当截取后的piv_str 中不存在分割符时,判断piv_strpiv_str1是否相等,相等 res=1
  74. IF piv_str_a = piv_str_b THEN
  75. res:= 1;
  76. END IF;
  77. -- 无论最后是否相等,都跳出循环
  78. EXIT;
  79. END IF;
  80. END LOOP;
  81. -- 结束循环
  82. END IF;
  83. piv_str_a := substr(piv_str_a,l_idx_a+length(p_sep));
  84. ELSE
  85. -- 当截取后的piv_str 中不存在分割符时,判断piv_strpiv_str1是否相等,相等 res=1
  86. IF piv_str_a = piv_str_b THEN
  87. res:= 1;
  88. END IF;
  89. -- 无论最后是否相等,都跳出循环
  90. EXIT;
  91. END IF;
  92. END LOOP;
  93. -- 结束循环
  94. END IF;
  95. -- 返回res
  96. RETURN res;
  97. 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. 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 ...

  2. Jesery客户端工具类

    public class JerseyClientUtil { public static<T> T sendMsg(String url,Object object,Class<T ...

  3. [JS] 数据双向绑定原理

    通常在前端开发过程中,经常遇到需要绑定两个甚至多个元素之间的值,比如将input的值绑定到一个h1上,改变input的值,h1的文字也自动更新. <h1 id="title" ...

  4. Global.asax和HttpModule的执行顺序

    Application_Start-->用户自定义的HttpModule-->Application_BeginRequest   (注册->调用) 看到Init方法(在用户自定义的 ...

  5. ASP.NET Core 2 学习笔记(三)中间件

    之前ASP.NET中使用的HTTP Modules及HTTP Handlers,在ASP.NET Core中已不复存在,取而代之的是Middleware.Middleware除了简化了HTTP Mod ...

  6. mvc基础知识(1)

    复制大佬的,侵权请联系我主动删除 1.js/css合并 在之前的crud例子中,我们引入js/css脚本的方式和平常的web开发一样 <script src="~/Scripts/jq ...

  7. With语句上下文管理

    在平时工作中总会有这样的任务,它们需要开始前做准备,然后做任务,然后收尾清理....比如读取文件,需要先打开,读取,关闭 这个时候就可以使用with简化代码,很方便 1.没有用with语句 1 2 3 ...

  8. Django + DRF + Elasticsearch 实现搜索功能

    django使用haystack来调用Elasticsearch搜索引擎  如何使用django来调用Elasticsearch实现全文的搜索 Haystack为Django提供了模块化的搜索.它的特 ...

  9. jzoj4424

    20%:暴力枚舉每一條邊有沒有被選到,然後使用并查集判斷聯通性 這樣子有20分,但是我考試寫掛了所以1分也沒有 100%:這道題2000的數據範圍,使用指數級搜索會tle,需要更加好的方法 這道題中, ...

  10. docker容器的基本操作

    docker容器是独立运行的一个或一组应用,以及它们的运行态环境.下面具体介绍如何管理一个容器,包括容器的创建,启动和停止等. 启动容器 基于镜像新建一个容器并启动 将终止状态的容器重新启动 新建并启 ...