Sql DB2 delete和with语句

Sql DB2 delete和with语句,sql,db2,sql-delete,Sql,Db2,Sql Delete,以下嵌套的DB2 SQL查询不起作用。这有嵌套的DELETE和WITH语句 delete from ADDRESS where ADDRESS_ID in (with addr (ADDRESS_ID) as (select a.ADDRESS_ID from ADDRESS a where a.MEMBER_ID between 50000000 and 999999999 and a.STATUS='T' and a.LASTCREATE < (current ti

以下嵌套的DB2 SQL查询不起作用。这有嵌套的DELETE和WITH语句

delete from ADDRESS 
where 
    ADDRESS_ID in (with     addr (ADDRESS_ID) as (select a.ADDRESS_ID from ADDRESS a where a.MEMBER_ID between 50000000 and 999999999 and a.STATUS='T' and a.LASTCREATE < (current timestamp - 42 days)), 
                addrorder (ADDRESS_ID) as ( select ad.ADDRESS_ID from ADDR ad LEFT OUTER JOIN ORDERS o on o.ADDRESS_ID = ad.ADDRESS_ID where o.ADDRESS_ID is null), 
                addordi (ADDRESS_ID) as ( select ao.ADDRESS_ID from ADDRORDER ao LEFT OUTER JOIN ORDERITEMS oi on oi.ADDRESS_ID=ao.ADDRESS_ID where oi.ADDRESS_ID is null), 
                addordia (ADDRESS_ID) as ( select aoi.ADDRESS_ID from ADDORDI aoi LEFT OUTER JOIN ORDERITEMS oi ON oi.ALLOCADDRESS_ID=aoi.ADDRESS_ID where oi.ALLOCADDRESS_ID is null)
                select distinct aoia.ADDRESS_ID from ADDORDIA aoia LEFT OUTER JOIN HD_MEMBER_SUBSCR ms ON ms.ADDRESS_ID=aoia.ADDRESS_ID where ms.ADDRESS_ID is null fetch first 800000 rows only for read only with ur);

使用最简单的解决方案:您的查询不需要任何CTE。一般来说,在以下情况下使用CTE:

您试图抽象出一组连接/操作,即通常作为视图创建的连接/操作 您计划多次引用结果 有一个相关的方法用于命名聚合结果集,但这可以通过连接子查询完成

对于简单的情况,不必麻烦。几乎所有版本的DB2中都应该运行以下内容,除非先获取,否则几乎所有RDBMS中都应该运行以下内容:

DELETE FROM Address 
WHERE member_id >= 50000000 
      AND member_id < 1000000000
      AND status = 'T'
      AND lastCreate < CURRENT_TIMESTAMP - 42 DAYS
      AND NOT EXISTS (SELECT '1'
                      FROM Orders
                      WHERE Orders.address_id = Address.address_id)
      AND NOT EXISTS (SELECT '1'
                      FROM OrderItems
                      WHERE OrderItems.addressId = Address.address_id
                            OR OrderIterms.allocAddress_id = Address.address_id)
      AND NOT EXISTS (SELECT '1'
                      FROM HD_Member_Subscr
                      WHERE HD_Member_Subscr.address_id = Address.address_id)
FETCH FIRST 800000 ROWS ONLY
WITH UR
事实上,我想知道只读是不是问题的一部分。请注意,如果没有ORDERBY子句,行的顺序将是随机的,尽管很可能是由地址id决定的


请注意,我已经将BETWEEN替换为我个人认为应该弃用的独占范围,并且出于一致性原因,提倡为偶数整数范围显式定义范围。

我同意@Clockwork Muse的观点,这里并不真的需要CTE,而且我认为DB2不支持带有DELETE语句的CTE,无论如何,至少在卢

既然您说notexists子句的性能不好,您可以尝试使用LEFT连接的这种替代方法,但我不确定它是否会更好。下面的逻辑假设表中的地址字段(地址字段除外)定义为NOTNULL(如果不是这种情况)

如果你真的要删除足够多的条目,一次需要删除80万条,那么你可能有很多数据,不管你如何处理,它都会相当慢

还有,你为什么和你的朋友在一起?是否确实要删除未提交的行

DELETE FROM Address 
WHERE member_id >= 50000000 
  AND member_id < 1000000000
  AND status = 'T'
  AND lastCreate < CURRENT_TIMESTAMP - 42 DAYS

  AND address_id IN (
    SELECT address_id FROM (
        SELECT
             A.address_ID
            ,ROW_NUMBER() OVER () AS RN
        FROM Address     A
        LEFT JOIN Orders O
          ON O.address_id = A.address_id
        LEFT JOIN OrderItems OI
          ON OI.addressId = A.address_id
        LEFT JOIN OrderItems OI2
          ON OI2.allocAddress_id = A.address_id
        LEFT JOIN HD_Member_Subscr H
          ON H.address_id= A.address_id
        WHERE O.addressId         IS NULL
          AND OI.addressId        IS NULL
          AND OI2.allocAddress_id IS NULL
          AND H.address_id        IS NULL
    ) T1
    WHERE RN <= 800000
  )

不工作怎么办?你犯了什么错误?以及DB2的哪个版本/平台,因为有些人根本不支持这种语法。我确实有上述疑问。但是,在查询中使用notexists会降低性能。还有其他解决方案吗?好吧,您可以按照@bhamby的建议去做,除非您可以向我们指出您的DB2版本/平台可能支持更好的东西。如果您的第一个查询没有运行,您怎么知道这会降低性能?必要时发布解释计划。抛出以下错误[错误代码:-104,SQL状态:42601]DB2SQL错误:SQLCODE=-104,SQLSTATE=42601,SQLERRMC=;。地址\u id为空;,驾驶员=4.13。127@user3175639你在哪个站台?大型机?Linux/Unix/Windows?iSeries?事实上,假设您在LUW上,问题是删除不支持先使用获取。我有点忘了那是行不通的。如果您确实需要限制,可以在我的最新编辑中使用建议的选项。