【问题标题】:Rewrite these DB2 SUBQUERY into a Join将这些 DB2 SUBQUERY 重写为 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 相比。为工作选择更好的工具(查询生成器)可能是更好的选择。

标签: sql date db2 subquery


【解决方案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
猜你喜欢
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-27
  • 1970-01-01
  • 2016-05-27
  • 2011-10-30
相关资源
最近更新 更多