在SQL的SELECT中实现循环查找、双层和多层循环(迭代)查找 SQL怎样实现编 ...

立山  论坛元老 | 2025-1-23 02:16:54 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1029|帖子 1029|积分 3087

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
在SQL的SELECT中实现循环查找、双层和多层循环(迭代)查找 SQL怎样实现编程语言的for循环查询 MySQL的Select子查询。
一、背景

在查询表极大,可能需要利用特定的查询索引的时间,利用SELECT子查询会比利用Inner Join查询服从要高。
如,我需要知道美国站点的在线listing数。普通的查询语句,直接利用Inner Join查询会由于店肆数目出现极大的查询性能问题。若店肆少,可能会几秒,随着店肆多起来,查询等待时间可能成百上千倍的增长,而不是预期的线性增长。甚至许多时间,会直接卡死。(原表上亿行)。
利用循环式查找则是将店肆表作为主表,然后嵌套SELECT子查询来实现。有点类似于每个店肆都是用编程语言的for循环,来逐条执行。这种方式快速且稳固。当表格极大,且需要用到特定的索引时,查询性能提拔尤为显着。(注意,这里店肆表才几百个店肆,而listing有上亿)
二、一层迭代(一层循环)

①需求:查找以深圳开头、国家为美国的店肆在平台的美国站点的在线listing数。

②、Inner Join实现

  1. /*
  2. 普通Inner Join。
  3. 时间:45.067
  4. */
  5. select
  6.     os.OrderSourceID
  7.     , count(1) listing表在线listing数
  8. from sys_ordersource os
  9. inner join m_ebay_listing el on el.OrderSourceId=os.OrderSourceID
  10. where os.CustomerID=1
  11.     and os.OrderSourceType=2
  12.     and os.OrderSourceCountry = 'US'
  13.     and os.OrderSourceName like '深圳%'
  14.     and el.SiteCode='US'
  15.     and el.OnlineStatus=1
  16. group by os.OrderSourceId
  17. ;
复制代码
③、嵌套查询实现、迭代查询的子查询

  1. /*
  2. SELECT 子查询
  3. 时间:6.570
  4. */
  5. select
  6.     os.OrderSourceID
  7.     , (
  8.         select
  9.            count(1)
  10.         from m_ebay_listing el
  11.         where el.OrderSourceId=os.OrderSourceID
  12.         and el.SiteCode='US'
  13.         and el.OnlineStatus=1
  14.     ) listing表在线listing数
  15. from sys_ordersource os
  16. where os.CustomerID=1
  17.     and os.OrderSourceType=2
  18.     and os.OrderSourceCountry = 'US'
  19.     and os.OrderSourceName like '深圳%'
  20. ;
复制代码
三、两层迭代(两层循环)

①需求:在2025年1月15号到2025年1月20号,品级为3、国家为美国的深圳店肆的天天刊登成功的listing数

注:ap_autopublish_ebay_queue 队列表有几亿的数据。
②单层with的两层迭代查询

  1. /*
  2. 方式一、美国站点的中级店铺,在1月15号到1月20号每日的刊登成功量。
  3. 时间:1.914s
  4. 居然比下面那个快这么多。
  5. */
  6. WITH RECURSIVE temp_dateTable AS (
  7.   SELECT 20250115 AS datekey
  8.   UNION ALL
  9.   SELECT date_format(date_add(CONVERT(datekey, CHAR),interval 1 day), "%Y%m%d")+0
  10.   FROM temp_dateTable
  11.   WHERE datekey < 20250120
  12. )
  13. select
  14.         dt.datekey
  15.         , os.OrderSourceID
  16.         , (
  17.             select
  18.                 count(1) 数量
  19.             from ap_autopublish_ebay_queue peq
  20.             where peq.CustomerId=1
  21.                 and peq.MarketId=2
  22.                 and peq.date=dt.datekey
  23.                 and peq.OrderSourceId = os.OrderSourceID
  24.                 and peq.Status='success'
  25.         ) 刊登成功数
  26. from temp_dateTable dt
  27. inner join sys_ordersource os on 1=1
  28. inner join sys_ebay_odersource_level eol on os.CustomerID=eol.CustomerID and os.OrderSourceID=eol.OrderSourceID
  29. where os.CustomerID=1
  30.         and os.OrderSourceType=2
  31.         and os.OrderSourceName like '直发%'
  32.         and os.OrderSourceCountry='US'
  33.         and eol.StoreLevel=3
复制代码
③两层with的两层迭代查询:可借鉴用来实现多层迭代查询

  1. /*
  2. 方式二、美国站点的中级店铺,在1月15号到1月20号每日的刊登成功量。
  3. 时间:17.343s
  4. */
  5. WITH RECURSIVE temp_dateTable AS (
  6.   SELECT 20250115 AS datekey
  7.   UNION ALL
  8.   SELECT date_format(date_add(CONVERT(datekey, CHAR),interval 1 day), "%Y%m%d")+0
  9.   FROM temp_dateTable
  10.   WHERE datekey < 20250120
  11. ), tos as (
  12.         select
  13.                 os.OrderSourceID
  14.         from sys_ordersource os
  15.         inner join sys_ebay_odersource_level eol
  16.             on os.CustomerID=eol.CustomerID and os.OrderSourceID=eol.OrderSourceID
  17.         where os.CustomerID=1
  18.             and os.OrderSourceType=2
  19.             and os.OrderSourceName like '直发%'
  20.             and os.OrderSourceCountry='US'
  21.             and eol.StoreLevel=3
  22. )
  23. select
  24.         dt.datekey
  25.         , tos.OrderSourceID
  26.         , (
  27.             select
  28.                 count(1) 数量
  29.             from ap_autopublish_ebay_queue peq
  30.             where peq.CustomerId=1
  31.                 and peq.MarketId=2
  32.                 and peq.date=dt.datekey
  33.                 and peq.OrderSourceId = tos.OrderSourceID
  34.                 and peq.Status='success'
  35.         ) 刊登成功数
  36. from temp_dateTable dt
  37. inner join tos on 1=1
复制代码
四、多层迭代(多层循环)

请参考三、两层迭代(两层循环)中的第三小节③两层with的两层迭代查询,通过新增多层with实现。
(实例:略)

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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

立山

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