2016-02-27 32 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