将这些 DB2 SUBQUERY 重写为 Join
Posted
技术标签:
【中文标题】将这些 DB2 SUBQUERY 重写为 Join【英文标题】:Rewrite these DB2 SUBQUERY into a Join 【发布时间】:2016-01-28 18:40:59 【问题描述】:我有一些需要查询数据库的业务规则。现在下面的 sql 正在使用子查询,但我想将每个查询更改为一个 join 语句。
column oditnr:项目编号 column odredt:下单后的天数 列 odbcsn:客户#我的数据库是 DB2,但我使用 mysql 创建了一个 sql fiddle http://www.sqlfiddle.com/#!9/3d10ae/3
我需要检查客户是否在过去 60 天内购买了编号为 1025926 的商品 如果查询返回结果,则客户购买了该商品。
SELECT ord1.oditnr, ord1.odredt, itm.imdesc
FROM orderdetails ord1
LEFT JOIN items itm ON ord1.oditnr = itm.imitnr
WHERE EXISTS (SELECT *
FROM orderdetails ord2
WHERE ord1.odbcsn = ord2.odbcsn
AND ord2.oditnr = '1022925'
AND odredt >= VARCHAR_FORMAT(CURRENT TIMESTAMP - 60 DAYS, 'YYYYMMDD') )
AND ord1.odbcsn = '11677'
ORDER BY odredt desc ;
我需要检查客户在过去 60 天内是否没有购买过编号为 2521809 的商品 如果查询返回结果,则客户尚未购买该商品。
SELECT ord1.oditnr, ord1.odredt, itm.imdesc
FROM orderdetails ord1
LEFT JOIN items itm ON ord1.oditnr = itm.imitnr
WHERE NOT EXISTS (SELECT *
FROM orderdetails ord2
WHERE ord1.odbcsn = ord2.odbcsn
AND ord2.oditnr = '2521809'
AND odredt >= VARCHAR_FORMAT(CURRENT TIMESTAMP - 60 DAYS, 'YYYYMMDD') )
AND ord1.odbcsn = '11677'
ORDER BY odredt desc ;
【问题讨论】:
想评论为什么你需要加入? 我正在使用mistic100.github.io/jQuery-QueryBuilder 创建一个接口来构建查询。子查询对于插件来说太复杂了 你有什么问题? 我需要一些帮助,将上面的 2 个查询转换为不使用子查询的连接 请记住,联接的性能可能会更差,尤其是与not exists
相比。为工作选择更好的工具(查询生成器)可能是更好的选择。
【参考方案1】:
如果您找不到其他支持子查询的工具,您可以尝试以下方法:
SELECT ord1.oditnr, ord1.odredt, itm.imdesc
FROM orderdetails ord1
INNER JOIN orderdetails ord2
ON ord1.odbcsn = ord2.odbcsn
LEFT JOIN items itm ON ord1.oditnr = itm.imitnr
WHERE ord2.oditnr = '1022925'
AND ord2.odredt >= (CURDATE() - interval 60 day + 0)
AND ord1.odbcsn = '11677'
ORDER BY odredt desc ;
-- Updated this query
SELECT ord1.oditnr, ord1.odredt, itm.imdesc
FROM orderdetails ord1
LEFT JOIN orderdetails ord2
ON ord1.odbcsn = ord2.odbcsn
LEFT JOIN items itm ON ord1.oditnr = itm.imitnr
WHERE ord2.oditnr = '2521809'
AND ord2.odredt >= (CURDATE() - interval 60 day + 0)
AND ord1.odbcsn = '11677'
ORDER BY odredt desc ;
更新:我调整了底部查询以将 INNER JOIN 更改为 LEFT JOIN。但是,与 OP 发布的查询不同,如果未找到 ord2.oditnr,此版本将返回一个空集 - 这从直觉上讲是有道理的 - 如果未找到订单号,则不返回任何行。如果没有某种子查询,就真的没有办法返回一个基于非的集合
至少,顶部查询与 OP 输出相匹配。
【讨论】:
恐怕内连接无法帮助找到不存在的记录。 此查询适用于转换 WHERE EXISTS。 我还想要一个查询,我可以使用任何项目编号来表示不存在。例如。客户 (11677) 实际购买了商品 (1025926),因此 NOT EXISTS 查询正确地不返回任何结果。 sqlfiddle.com/#!9/357b5/6以上是关于将这些 DB2 SUBQUERY 重写为 Join的主要内容,如果未能解决你的问题,请参考以下文章
Mysql join with subquery join 使用相关名称
MySQL Left Join Subquery with *
LEFT JOIN 和 SUBQUERY 与空列 / null 作为结果