2016-02-27 74 views
1

我看到了一些近似的答案,但我無法將它們放入我的場景中。更新使用WITH CLAUSE

我在PL/SQL(的Oracle 11g)如下: (編輯:我清理SQL一點使它右)

WITH t AS 
(
    SELECT case_nbr, 
      type_cd, 
      subtype_cd, 
      class_nbr, 
      case_dt, 
      SUM(fhits) fhits_sum, 
      COUNT(fhits) hit_count 
    FROM DDEL.MYCASE 
    GROUP BY case_nbr, 
      type_cd, 
      subtype_cd, 
      class_nbr, 
      case_dt    
    ) 
    SELECT ROUND(mc.fhits/t.fhits_sum * mc.qty) new_qty , t.*, mc.fhits, mc.qty 
    FROM t 
    JOIN DDEL.MYCASE mc 
    ON t.case_nbr = mc.case_nbr 
    AND t.type_cd = mc.type_cd 
    AND t.subtype_cd = mc.subtype_cd 
    AND t.class_nbr = mc.class_nbr 
    AND t.case_dt = mc.case_dt 
    WHERE t.fhits_sum > 1000 
    AND t.hit_count > 1 
); 

結果給我(我只是編號無關列,使其更適合):

new_qty 1 2 3 4 5    6 fhits qty 
57 10 E S 8 01-DEC-15 133 2 999 77 
20 10 E S 8 01-DEC-15 133 2 934 77 

這找工作......但是,我想要做的就是更新該查詢在這種情況下,結果...兩個記錄。我想用new_qty(你會看到57和20)修改mc.qty列(你看77的地方)。

我很難得到一個更新使用WITH子句和這個結果集。我想我必須做更復雜的事情,但希望有人可以在這裏看到一個簡單的方法來添加更新。請記住,查詢正在查找一組具有大量數據的不同記錄,這些記錄匹配的次數不止一次,並且符合以下條件:一起使fhits列的總和超過1000的值...只有那麼我想要做到這一點。

我剛剛在這最後一天半的時間裏看了太久,我錯過了一些明顯的東西。感謝您的幫助

回答

-1

MERGE命令將是正確的答案。 這也將是最佳做法。

1

我想知道你爲什麼使用LEFT OUTER JOIN合併來自MYCASE mc的行和來自t的聚合結果?
這意味着可能存在case_nbr, type_cd, subtype_cd, class_nbr, case_dt,t的組合,這在MYCASE mc中不存在,但由於這些值來自MYCASE表,因此這是坦率地不可能的,除非這些列中的某些列可以包含(並且包含)NULL值。
但在後一種情況下(連接列可以包含NULL),查詢中的連接條件有缺陷,因爲不考慮NULL。
在這種情況下,連接條件必須包含如下內容:... AND (t.colX = m.colX OR t.colX IS NULL AND m.colX IS NULL) ...而不是簡單的AND t.colX = m.colX


無論如何,我們將用新值更新qty列。
Assumming,參與連接條件的所有列不能包含空值,那麼你的查詢可以rewiriteen以這種方式使用直加盟:

SELECT mc.qty, 
     ROUND(mc.qty * mc.fhits/t.fhits_sum) new_qty 
    FROM (
     SELECT case_nbr, type_cd, subtype_cd, class_nbr, case_dt, 
      SUM(fhits) fhits_sum, COUNT(fhits) hit_count 
     FROM MYCASE 
     GROUP BY case_nbr, type_cd, subtype_cd, class_nbr, case_dt 
) t 
    JOIN MYCASE mc ON (
    mc.case_nbr = t.case_nbr AND mc.type_cd = t.type_cd 
    AND mc.subtype_cd = t.subtype_cd AND mc.class_nbr = t.class_nbr 
    AND mc.case_dt = t.case_dt 
) 
    WHERE t.fhits_sum > 1000 
    AND t.hit_count > 1 

上面的查詢只給出兩個欄目:qty是來自MYCASE表,和new_qty這是一個新值,其中qty必須更新。

所有你需要的是使用上面的查詢來更新創建內嵌視圖:

UPDATE ( the_above_query_as_inline_view) 
SET qty = new_qty; 

那就是:

UPDATE (
     SELECT mc.qty, 
      ROUND(mc.qty * mc.fhits/t.fhits_sum) new_qty 
     FROM (
      SELECT case_nbr, type_cd, subtype_cd, class_nbr, case_dt, 
       SUM(fhits) fhits_sum, COUNT(fhits) hit_count 
      FROM MYCASE 
      GROUP BY case_nbr, type_cd, subtype_cd, class_nbr, case_dt 
    ) t 
     JOIN MYCASE mc ON (
     mc.case_nbr = t.case_nbr AND mc.type_cd = t.type_cd 
     AND mc.subtype_cd = t.subtype_cd AND mc.class_nbr = t.class_nbr 
     AND mc.case_dt = t.case_dt 
    ) 
     WHERE t.fhits_sum > 1000 
     AND t.hit_count > 1 
) 
SET qty = new_qty; 

附記:在你的第一個子查詢中DISTINCT子句冗餘:

SELECT DISTINCT case_nbr, 
        type_cd, 
        subtype_cd, 
        class_nbr, 
        case_dt, 
        SUM(fhits) fhits_sum, 
        COUNT(fhits) hit_count 
    FROM DDEL.MYCASE 
    GROUP BY case_nbr, 
      type_cd, 
      subtype_cd, 
      class_nbr, 
      case_dt 

如果使用GROUB BY和聚合,則結果總是唯一的,不需要添加DISTINCT

這個查詢:SELECT DISTINCT a,b,c,d FROM table是eqivalent到:

SELECT a,b,c,d 
FROM table 
GROUP BY a,b,c,d 
+0

感謝那些運作良好。至於Distinct和Outer Join,你是對的......它通過多次交換我的代碼試圖讓它與更新一起工作。在發佈之前,我應該清理它。如果有人想要使用那裏的什麼,我會將其修正爲其他人 – Mark