SQL 解析 with as

打印 上一主题 下一主题

主题 1798|帖子 1798|积分 5394

 sql的运行次序

 
  1. <select id="getTrendList"  parameterType="java.util.HashMap" resultType="java.util.Map">
  2.         <![CDATA[
  3.         WITH
  4.         -- 生成连续年份列表(当前年前8年到前1年)
  5.         year_range AS (
  6.         SELECT EXTRACT(YEAR FROM SYSDATE) - 8 + LEVEL - 1 AS INSPECTION_YEAR
  7.         FROM DUAL
  8.         CONNECT BY LEVEL <= 8
  9.         ),
  10.         -- 原始数据解析
  11.         split_data AS (
  12.         SELECT
  13.         SBBH,
  14.         EXTRACT(YEAR FROM BCJYRQ) AS INSPECTION_YEAR,
  15.         (SELECT MIN(TO_NUMBER(REGEXP_SUBSTR(NVL(FT1, '0/0'), '\d+\.?\d*', 1, LEVEL)))
  16.         FROM DUAL
  17.         CONNECT BY LEVEL <= REGEXP_COUNT(NVL(FT1, '0/0'), '/') + 1
  18.         ) AS FT1_MIN,
  19.         (SELECT MIN(TO_NUMBER(REGEXP_SUBSTR(NVL(FT2, '0/0'), '\d+\.?\d*', 1, LEVEL)))
  20.         FROM DUAL
  21.         CONNECT BY LEVEL <= REGEXP_COUNT(NVL(FT2, '0/0'), '/') + 1
  22.         ) AS FT2_MIN,
  23.         (SELECT MIN(TO_NUMBER(REGEXP_SUBSTR(NVL(TT, '0/0'), '\d+\.?\d*', 1, LEVEL)))
  24.         FROM DUAL
  25.         CONNECT BY LEVEL <= REGEXP_COUNT(NVL(TT, '0/0'), '/') + 1
  26.         ) AS TT_MIN
  27.         FROM sbjcpg_hysb_jyxx
  28.         WHERE
  29.         SBBH = #{sbbh}
  30.         AND EXTRACT(YEAR FROM BCJYRQ) BETWEEN EXTRACT(YEAR FROM SYSDATE) - 8 AND EXTRACT(YEAR FROM SYSDATE) - 1
  31.         )
  32.         -- 最终结果(左连接补全年份)
  33.         SELECT
  34.         #{sbbh} AS SBBH,  -- 固定设备编号
  35.         yr.INSPECTION_YEAR AS YEAR,
  36.         MIN(sd.FT1_MIN) AS FT1,  -- 无数据时为 NULL
  37.         MIN(sd.FT2_MIN) AS FT2,
  38.         MIN(sd.TT_MIN) AS TT
  39.         FROM year_range yr
  40.         LEFT JOIN split_data sd
  41.         ON yr.INSPECTION_YEAR = sd.INSPECTION_YEAR
  42.         GROUP BY yr.INSPECTION_YEAR
  43.         ORDER BY yr.INSPECTION_YEAR
  44.          ]]>
  45.     </select>
复制代码
with as

用时创建临时表,让代码看起来更轻便,节约性能
  1. WITH
  2.   cte1 AS (SELECT ... FROM ...),
  3.   cte2 AS (SELECT ... FROM cte1 WHERE ...)
  4. SELECT * FROM cte2;
复制代码

 EXTRACT

是用来提取
 dual


DUAL 表是 Oracle 中一个简单但强盛的工具,主要用于实行与数据表无关的快速计算、函数调用或测试。明白它的用途可以显著提升 SQL 编写的效率和灵活性。


sysdate 

 

level

 



  1. SELECT MIN(TO_NUMBER(REGEXP_SUBSTR(NVL(FT1, '0/0'), '\d+\.?\d*', 1, LEVEL)))
  2.         FROM DUAL
  3.         CONNECT BY LEVEL <= REGEXP_COUNT(NVL(FT1, '0/0'), '/') + 1
复制代码

Oracle中的日期存储 

 参考链接
使用Oracle SQL查询提取日期中的年份高效本领详解 - 云原生实践
ORACLE——EXTRACT() 截取日期时间的函数使用 - 九零大叔芭蕉 - 博客园
 蓝色区域的主要逻辑
核心部分


主查询结构 
  1. SELECT
  2.     SBBH,  -- 设备编号
  3.     EXTRACT(YEAR FROM BCJYRQ) AS INSPECTION_YEAR,  -- 检测年份
  4.     (子查询) AS FT1_MIN  -- 计算 FT1 字段的最小值
  5. FROM sbjcpg_hysb_jyxx
  6. WHERE
  7.     SBBH = #{sbbh}  -- 筛选指定设备编号
  8.     AND EXTRACT(YEAR FROM BCJYRQ) BETWEEN
  9.         EXTRACT(YEAR FROM SYSDATE) - 8  -- 起始年份(当前年-8)
  10.         AND EXTRACT(YEAR FROM SYSDATE) - 1  -- 结束年份(当前年-1)
复制代码

拆解字符串并计算最小值

  1. (
  2.     SELECT MIN(TO_NUMBER(REGEXP_SUBSTR(NVL(FT1, '0/0'), '\d+\.?\d*', 1, LEVEL)))
  3.     FROM DUAL
  4.     CONNECT BY LEVEL <= REGEXP_COUNT(NVL(FT1, '0/0'), '/') + 1
  5. ) AS FT1_MIN
复制代码
 这个查询中用到了FT1字段,但是他 只从dual表中查的 ,其实这是
关联子查询




 NVL 函数


 Oracle REGEXP_SUBSTR() 函数使用指南Oracle REGEXP_SUBSTR() 是一个内置函数,它从一个给定的源字符串中搜索并返回一个与给定的正则表达式匹配的字符串。
https://www.sjkjc.com/oracle-ref/regexp_substr/

 REGEXP_SUBSTR()


 



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表