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;

  

然后完美解决

 

转载于:https://www.cnblogs.com/dmeck/p/9771779.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33854644/article/details/93160740

智能推荐

tf实现Focal-Loss_focal loss tf-程序员宅基地

文章浏览阅读966次。tf实现Focal−Losstf实现Focal-Losstf实现Focal−Loss_focal loss tf

sql server 2000 示例数据库 Pubs 全库脚本 SQLServer2000 自带数据库-程序员宅基地

文章浏览阅读232次。/* *//* InstPubs.SQL - Creates the Pubs database */ /* *//*** Copyright Microsoft, Inc. 1994 - 2000** All Rights Reserved.*/SET NOCOUNT ONGOset nocount onset dateformat mdyUSE masterdeclare @d..._sql2000中自带的pubs数据库中的表

【无标题】App iOS端适配iOS 15系统_lsapplicationqueriesschemes 超过 50 怎么办-程序员宅基地

文章浏览阅读2.6k次。各位好:App iOS端适配iOS 15系统,适配后将使用新的xcode 13打包提交App Store。一、适配内容:1、新增了iPhone 13 mini机型(尺寸同iPhone12 mini),5.4 英寸 (对角线) OLED 全面屏,屏幕分辨率为2340 x 1080 像素。如果是通过分辨率来判断则需要增加一个模式。 #define iPhone13mini ([UIScreen instancesRespondToSelector:@selector(currentMo_lsapplicationqueriesschemes 超过 50 怎么办

抓包工具Fiddler的下载安装使用_fiddler抓包下载-程序员宅基地

文章浏览阅读497次。右侧显示就是我们主机发送http/https请求的记录。如果我们要查看某一次访问,可以双击该记录,在右侧就会显示这次http请求的内容以及返回的响应的内容。右键全选,点击remove,选择selected sessions,就能删除选择的sessions。安装过程只用一路next即可;_fiddler抓包下载

html语言ppt,htmlppt课件-程序员宅基地

文章浏览阅读642次。PPT内容这是htmlppt课件,关于第2章Web编程技术,包括了HTML的发展历史,HTML的基本框架,HTML的各种常用标记:文字标记、图片标记、超级链接标记,CSS的基本使用方法,如何让CSS与HTML协同工作,JavaScript中的变量、数组、表达式、运算符、流程控制语句,JavaScript的函数、内置对象、浏览器对象的层次和DOM模型的建立和使用等内容,欢迎点击下载。第2章 Web编..._html if elseppt课件

solr html显示,Solr查询界面-程序员宅基地

文章浏览阅读259次。您可以使用查询界面将搜索查询提交给 Solr 集合并分析结果。在下面截图中的例子中,查询已经被提交,并且界面显示了作为 JSON 形式发送到浏览器的查询结果。在这个例子中,genre:Fantasy 的查询被发送到 “films” 集合。表单中的所有其他选项都使用了默认值,下表中对此进行了简要介绍,本指南的后面部分将对此进行详细介绍。该响应显示在窗体的右侧。对 Solr 的请求只是简单的 HTTP..._solr查询界面

随便推点

RuntimeError: split_size can only be 0 if dimension size is 0, but got dimension size of 2-程序员宅基地

文章浏览阅读624次。使用pytorch时遇到下面的问题RuntimeError: split_size can only be 0 if dimension size is 0, but got dimension size of 2原因:训练的batch size 比使用的GPU数量少,导致上述问题。解决办法增加batch size数值,保证为GPU数量整数倍。参考:1.https://discuss.pytorch.org/t/concatenating-images/40961/10_split_size can only be 0 if dimension size is 0, but got dimension size of 1

RabbitMQ订阅发布的消息,通过WebSocket实现数据实时推送到前端_rabbitmq怎么返回给前端数据-程序员宅基地

文章浏览阅读7.3k次,点赞3次,收藏12次。一、架构简单概述 RabbitMQ消息队列服务善于解决多系统、异构系统间的数据交换(消息通知/通讯)问题,并且可以订阅和发布,而随着HTML5诞生的WebSocket协议实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。 因此,我们可以使用RabbitMQ的订阅发布技术,订阅后,当RabbitMQ端有新的数据就直接发布到指定的queue,订_rabbitmq怎么返回给前端数据

Mendix Excel导出介绍_mendix实现excel导出-程序员宅基地

文章浏览阅读320次。本文介绍了Excel导出的两种方式及成果展示_mendix实现excel导出

5 gtm 工作原理_基于GTM法的水泥稳定碎石力学性能研究-程序员宅基地

文章浏览阅读226次。文章来源:微信公众号”沥青路面“引 言众所周知,以水泥稳定碎石为代表的半刚性材料是中国目前使用最为广泛的基层材料,因为其力学性能优良、使用成本较低、原材料来源广泛和施工工艺简单等优点,水泥稳定碎石在未来十几年内仍将是中国使用最为广泛的基层材料。目前水泥稳定碎石在设计和施工方面存在一些问题,例如室内成型方式与实际道路受力状态存在一定差异;设计指标和施工检测指标相关性不足;对矿质石料级配的要求没有体现..._无侧限抗压强度与劈裂强度的的关系

黑科技,Python 脚本帮你找出微信上删除你好友的人_微信出现brandsessionholder-程序员宅基地

文章浏览阅读1.5k次。编者按:本文来自稀土掘金江昪编译自 Github:0x5e/wechat-deleted-friends “ 清理下[微笑],不用回。你的朋友圈没事也该清清了,打开设置,通用,功能,群助手,全选,把我的信息粘贴一下,就可以了,发送就知道谁把你删了,方便你清人,不清不知道 ,一清吓一跳。” 相信大家在微信上一定被上面的这段话刷过屏,群发消息应该算是微信上流传最广的找到删除好友的方法..._微信出现brandsessionholder

MySQL存储过程 游标循环的使用_存储过程 重复定义同名游标 会覆盖吗?-程序员宅基地

文章浏览阅读1.5k次。MySQL存储过程 游标循环的使用_存储过程 重复定义同名游标 会覆盖吗?

推荐文章

热门文章

相关标签