首页 > 数据库 >mysql 代码适配 postgresql 适配改写,优化案例(行转列 + 标量子查询改写)

mysql 代码适配 postgresql 适配改写,优化案例(行转列 + 标量子查询改写)

时间:2023-07-27 22:12:33浏览次数:39  
标签:rows postgresql .. NO 适配 time 改写 text CONT

最近在适配个MySQL应用的项目,各种SQL改成PG兼容的语法真的是脑壳痛,今天遇到个有意思的案例。

原 MySQL SQL语句:

SELECT
    DISTINCT
    l.MALL_NAME '项目',
    t.CONT_NO '合同编号',
    t.COMPANY_NAME '租户',
    t.STORE_NOS '铺位号',
    (select GROUP_CONCAT(r.FLOOR_NAME SEPARATOR ',') from bfbfbf r where r.id in (
        select s.FLOOR_ID from bsssb s where s.id in (
            select substring_index(substring_index(t1.store_ids, ',', b.help_topic_id + 1), ',', -1) a from bc t1
                left join mysql.help_topic b on b.help_topic_id < (length(t1.store_ids) - length(replace(t1.store_ids, ',', '')) + 1)
            where t1.CONT_NO = t.CONT_NO)
    )) '楼层',
        t.BRAND_NAME '品牌',
    l1.DICT_NAME '一级业态',
    l2.DICT_NAME '二级业态',
    l3.DICT_NAME '三级业态',
    t.LAYOUT_NAME '签约业态',
    t.SHARE_SQUARE '套内面积',
    t.RENT_SQUARE '计租面积',
    t.STRUCTURE_SQUARE '建筑面积',
    t.CONT_BEGIN_DATE A,
    IFNULL( CONT_FAIL_DATE, CONT_END_DATE ) B,
    CASE
        t.`STATUS`
    WHEN '0' THEN
    '未签约'
    WHEN '1' THEN
    '已审核'
    WHEN '2' THEN
    '已解约'
    WHEN '3' THEN
    '待审核'
    WHEN '5' THEN
    '已结算' ELSE '未知类型'
END '状态',
    (SELECT RENT_TYPE FROM bccdq e where e.CONT_NO = t.CONT_NO  and e.IS_DEL = '0' and e.RENT_TYPE is not null order by e.CREATED_DATE desc limit 1) '计租方式',
    (select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202301' and m1.CONT_NO = t.CONT_NO limit 1) '2023年1月销售额',
    (select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202301' and m1.CONT_NO = t.CONT_NO limit 1) '2023年1月销售笔数',
    (select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202302' and m1.CONT_NO = t.CONT_NO limit 1) '2023年2月销售额',
    (select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202302' and m1.CONT_NO = t.CONT_NO limit 1) '2023年2月销售笔数',
    (select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202303' and m1.CONT_NO = t.CONT_NO limit 1) '2023年3月销售额',
    (select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202303' and m1.CONT_NO = t.CONT_NO limit 1) '2023年3月销售笔数',
    (select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202304' and m1.CONT_NO = t.CONT_NO limit 1) '2023年4月销售额',
    (select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202304' and m1.CONT_NO = t.CONT_NO limit 1) '2023年4月销售笔数',
    (select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202305' and m1.CONT_NO = t.CONT_NO limit 1) '2023年5月销售额',
    (select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202305' and m1.CONT_NO = t.CONT_NO limit 1) '2023年5月销售笔数',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-01' and IS_DEL = '0'  limit 1) '2023年1月固定租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-02' and IS_DEL = '0'  limit 1) '2023年2月固定租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-03' and IS_DEL = '0'  limit 1) '2023年3月固定租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-04' and IS_DEL = '0'  limit 1) '2023年4月固定租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-05' and IS_DEL = '0'  limit 1) '2023年5月固定租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-01' and IS_DEL = '0'  limit 1) '2023年1月提成租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-02' and IS_DEL = '0'  limit 1) '2023年2月提成租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-03' and IS_DEL = '0'  limit 1) '2023年3月提成租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-04' and IS_DEL = '0'  limit 1) '2023年4月提成租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-05' and IS_DEL = '0'  limit 1) '2023年5月提成租金',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-01' and IS_DEL = '0'  limit 1) '2023年1月物业管理费',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-02' and IS_DEL = '0'  limit 1) '2023年2月物业管理费',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-03' and IS_DEL = '0'  limit 1) '2023年3月物业管理费',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-04' and IS_DEL = '0'  limit 1) '2023年4月物业管理费',
    (select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-05' and IS_DEL = '0'  limit 1) '2023年5月物业管理费'

FROM
    bc t
    LEFT JOIN bms l ON l.id = t.MALL_ID
    LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 4 ) l4 ON l4.ID = t.LAYOUT
    LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 3 ) l3 ON ( l3.ID = t.LAYOUT OR l4.PARENT_ID = l3.ID )
    LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 2 ) l2 ON ( l2.ID = t.LAYOUT OR l3.PARENT_ID = l2.ID )
    LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 1 ) l1 ON l2.PARENT_ID = l1.ID
WHERE
    l.MALL_TYPE = '1'
    and t.IS_DEL = '0'
    AND t.STATUS IN ( 1, 2, 5 )
    AND t.CONT_BEGIN_DATE <= '2023-05-31' AND IFNULL( CONT_FAIL_DATE, CONT_END_DATE ) >= '2023-01-01';

这条SQL是首先改成postgresql 兼容的语法,其实要改的内容不多,只有一个标量子查询处需要改写:

    (select GROUP_CONCAT(r.FLOOR_NAME SEPARATOR ',') from bfbfbf r where r.id in (
        select s.FLOOR_ID from bsssb s where s.id in (
            select substring_index(substring_index(t1.store_ids, ',', b.help_topic_id + 1), ',', -1) a from bc t1
                left join mysql.help_topic b on b.help_topic_id < (length(t1.store_ids) - length(replace(t1.store_ids, ',', '')) + 1)
            where t1.CONT_NO = t.CONT_NO)
    )) '楼层',

这里开发很聪明,使用了个小技巧使用 help_topic_id 递增的 help_topic_id 字段 + 进行 GROUP_CONCAT 函数进行行转列。

postgresql 由于没有 mysql.help_topic 表、GROUP_CONCAT、substring_index 这类函数所以需要等价改写上面的逻辑。

洽洽是这条SQL花了我几个小时来进行逻辑的等价改写,脑壳疼得厉害,还费烟,不过尝试了N次,查了不少函数终于给我改写出来了 

标签:rows,postgresql,..,NO,适配,time,改写,text,CONT
From: https://www.cnblogs.com/yuzhijian/p/17586235.html

相关文章

  • Android开发笔记:屏幕适配
    这几天刚刚接触了新的项目,做一个android客户端。本周的工作是完成客户端的UI界面和功能实现,但是对于Android开发最头疼的部分,即是对于纷杂的屏幕做适配的工作现在来说是最棘手的!图像显示所需的概念:像素:一幅图片的显示就是由许多显示着不同颜色的小方格组成的,这样的小方格就被称......
  • 低版本浏览器适配问题
    使用vue3+vite默认支持Chrome>=87chrome53:npminstall@vitejs/plugin-legacy-D//vite-config.jsimportlegacyfrom"@vitejs/plugin-legacy";legacy({targets:['defaults','ie>=11','chrome53'],......
  • android studio 学习数据适配器
    AndroidStudio学习数据适配器在Android开发中,我们经常需要将数据显示在界面上,而数据适配器(Adapter)就是帮助我们将数据和界面进行绑定的重要工具。在本文中,我们将学习如何使用AndroidStudio创建和使用数据适配器。数据适配器的作用数据适配器是连接数据和界面的桥梁,它负责将数......
  • PostgreSQL技术大讲堂 - 第24讲:TOAST技术
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。第24讲:TOAST技术内容1:Toast简介内容2:Toast的存储方式......
  • NineData已支持「最受欢迎数据库」PostgreSQL
    根据在StackOverflow发布的2023开发者调研报告中显示,PostgreSQL以45%vs41%的受欢迎比率战胜MySQL,成为新的最受欢迎的数据库。NineData也在近期支持了PostgreSQL,用户可以在NineData平台上进行创建数据库/Schema、管理用户与角色、导出数据、执行SQL等操作。另外,Ni......
  • 为什么 PostgreSQL 的适用性很强?
    说起使用数量最大的数据库SQLite它是全球最广泛部署的数据库引擎。它存在于你的手机中,存在于你的浏览器中,如果你搜索你的电脑,你也会在其中找到它的.db文件。SQLite受到Postgres的启发。其作者RichardHipp称SQLite是Postgres的“概念分支”。两者没有共享代码,但是Po......
  • PG-DBA培训07:PostgreSQL体系结构深入与源码解析 原创
    PostgreSQL体系结构深入解析,PostgreSQL数据库源码解析,initdb源码解析PostgreSQL数据库体系架构PostgreSQL数据库存储结构PostgreSQL数据库进程结构PostgreSQL数据库内存结构PostgreSQL数据库源码解析使用gdb跟踪分析PostgreSQL源码PostgreSQL源码解析之initdb初始化过程Postgre......
  • PG-DBA培训09:PostgreSQL用户权限与安全管理
    PostgreSQL数据库用户角色管理,访问控制管理,ssl访问,密码策略,审计管理,等保评测PostgreSQL数据库用户角色管理PostgreSQL访问控制管理PostgreSQLSSL安全访问PostgreSQL密码策略管理PostgreSQL审计管理PostgreSQL等保评测安全建议方案课程地址: https://edu.51cto.com/course/3......
  • PG-DBA培训08:PostgreSQL实例管理与参数文件
    PostgreSQL管理工具,参数文件源码分析,控制文件损坏恢复,系统表索引损坏,插件开发PostgreSQLPSQL管理工具使用PostgreSQL数据库参数文件PostgreSQL如何读取参数文件(源码)PostgreSQL数据库控制文件PostgreSQL控制文件损坏恢复案例PostgreSQL数据库日志文件PostgreSQL系统表与系......
  • Oracle数据类型与对应的PostgreSQL数据类型(oracle 19c 迁移到kingbase)
    Oracle数据类型与对应的PostgreSQL数据类型的映射:1.数值类型:-OracleNUMBER->PostgreSQLNUMERIC-OracleINTEGER->PostgreSQLINTEGER-OracleBINARY_FLOAT->PostgreSQLREAL-OracleBINARY_DOUBLE->PostgreSQLDOUBLEPRECISION2.字符串类型:-Or......