2014-01-09 127 views
0

以下嵌套的DB2 SQL查詢不起作用。這嵌套DELETE和WITH語句DB2刪除和語句

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); 
+0

「Not working」_how_?你遇到了什麼錯誤? DB2的版本/平臺(有些根本不支持這種語法) –

回答

0

使用什麼可能是最簡單的解決方案:您的查詢不需要任何CTE。一般來說,使用CTE時

  1. 你試圖抽象掉一些組加入/操作(即通常作爲一個視圖中創建)
  2. 您打算引用的結果不止一次
更多

(有一個相關的一個命名集合結果集,但可以用一個子查詢連接來完成)

對於簡單的條件,不要打擾。下面應該運行在DB2的幾乎每一個版本(和,除非FETCH FIRST,幾乎每一個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 

(實際上,我不知道是否FOR READ ONLY是問題的一部分,注意,沒有ORDER BY子句,行的順序將是隨機的 - 儘管可能由address_id反正)。

請注意,我已經換出了BETWEEN作爲排他性範圍(我個人認爲BETWEEN應該被棄用,並且爲了一致性的原因,主張爲偶數整數範圍明確定義範圍)。

+0

感謝您的答覆,我確實有上述查詢,但是在查詢中使用「NOT EXISTS」會降低性能。 – Samy

+0

那麼,你可以像@bhamby所建議的那樣,除非你能指出我們的DB2版本/平臺可以支持更好的東西。如果你的第一個查詢沒有運行,你怎麼知道這會降低性能?如果需要, –

0

我同意@ Clockwork-Muse在這裏你並不真的需要CTE,而且我不認爲DB2支持帶有DELETE聲明的CTE(至少在LUW上)。

由於您認爲NOT EXISTS條款的性能很差,您可以嘗試使用LEFT JOIN s這種替代方法,但我不確定它會好很多。下面的邏輯假定除地址字段以外的表中的地址字段被定義爲NOT NULL,如果不是這樣的話

如果你確實刪除了足夠多的條目來要求你這樣做,那麼八十萬條那麼你可能有很多數據,而且無論你如何處理它,它都會非常緩慢。

另外,爲什麼你有WITH UR?你真的想刪除未提交的行嗎?

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 
) 
+0

引發以下錯誤[錯誤代碼:-104,SQL狀態:42601] DB2 SQL錯誤:SQLCODE = -104,SQLSTATE = 42601,SQLERRMC =);。address_id IS NULL ; ,DRIVER = 4.13.127 – Samy

+0

@ user3175639:你在哪個平臺上?大型機? LINUX/UNIX/Windows的? i系列? – bhamby

+0

其實,假設你在LUW上,問題是'DELETE'不支持使用'FETCH FIRST'。有點下降了我的想法,那是行不通的。如果你真的需要一個限制,你可以在我最近的編輯中使用建議的選項。 – bhamby