【问题标题】:Update Query With Joins and Group by Clause使用联接和按子句分组更新查询
【发布时间】:2011-02-04 16:23:15
【问题描述】:

我有以下查询,我正在尝试用总金额更新 table1。 有没有办法在 1 步中做到这一点?

select e.id
     , p.id
     , case  
         when count(distinct e.item) = 1 then 100
         when count(distinct e.item) = 2 then 150
         when count(distinct e.item) = 3 then 200
         when count(distinct e.item) = 4 then 225
         when count(distinct e.item) = 5 then 275
         when count(distinct e.item) = 6 then 325
         when count(distinct e.item) = 7 then 375
         when count(distinct e.item) = 8 then 450
         when count(distinct e.item) = 8 then 470
       end as TotalPay
  from table1 p 
  join table2 e on e.id = '111111'
               and p.id=e.itemid
group by e.id, p.id

【问题讨论】:

    标签: sql oracle oracle10g sql-update


    【解决方案1】:

    用途:

    UPDATE TABLE1
       SET total = (SELECT CASE
                             WHEN COUNT(DISTINCT t2.item) = 1 THEN 100
                             WHEN COUNT(DISTINCT t2.item) = 2 THEN 150
                             WHEN COUNT(DISTINCT t2.item) = 3 THEN 200
                             WHEN COUNT(DISTINCT t2.item) = 4 THEN 225
                             WHEN COUNT(DISTINCT t2.item) = 5 THEN 275
                             WHEN COUNT(DISTINCT t2.item) = 6 THEN 325
                             WHEN COUNT(DISTINCT t2.item) = 7 THEN 375
                             WHEN COUNT(DISTINCT t2.item) = 8 THEN 450
                             WHEN COUNT(DISTINCT t2.item) = 9 THEN 470
                           END
                      FROM TABLE2 t2
                     WHERE t2.itemid = id
                       AND t2.id = '111111'
                  GROUP BY t2.id, t2.itemid)
     WHERE EXISTS(SELECT NULL
                    FROM TABLE2 t
                   WHERE t.itemid = id
                     AND t.id = '111111')
    
    • WHERE 子句是必需的,否则将处理所有 TABLE1 行。那些没有相关 TABLE2 行的,将被更新为NULL
    • Oracle(IME,最高 10g)不支持像 MySQL 和 SQL Server 这样的 UPDATE 子句中的 JOIN——您必须使用子查询(在本例中是相关的)。它也不允许您为正在更新的表定义表别名,因此当您在示例中看到省略表别名时 - 该列来自没有别名的表(正在更新的那个)

    【讨论】:

    • 在EXISTS下的子选择中,在WHERE子句中,id不应该以TABLE1为前缀吗?其他子选择也是如此。
    • @Andriy M:可以,但答案已经说明优化器看到列引用没有正确关联的表别名。
    • 我忽略了这一点,真丢人。对不起。
    • 仅供参考,由于某种原因,我没有成功地将别名排除在外。它似乎是从错误的桌子上拉出来的。而且我确实成功地在更新表上分配了一个别名。
    【解决方案2】:

    试试:

    update table1 p 
    set TotalPay = 
    (
    select case  
             when count(distinct e.item) = 1 then 100
             when count(distinct e.item) = 2 then 150
             when count(distinct e.item) = 3 then 200
             when count(distinct e.item) = 4 then 225
             when count(distinct e.item) = 5 then 275
             when count(distinct e.item) = 6 then 325
             when count(distinct e.item) = 7 then 375
             when count(distinct e.item) = 8 then 450
             when count(distinct e.item) = 8 then 470
           end as TotalPay
      from table2 e where p.id=e.itemid
                    and e.id = '111111'  
    )  
    

    正如在 cmets 中所指出的,即使在 table2 中没有匹配项,上述内容也会更新 table1 中的所有行 - 它会将列设置为 NULL。为避免添加 WHERE 子句 - 请参阅 OMGPonies 的答案。

    【讨论】:

    • 当没有匹配的e.itemid记录时不会写NULL吗?
    • @OMG Ponies,一旦我从用空值覆盖问题的糟糕记忆中恢复过来,你就会得到你的支持 :)
    猜你喜欢
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多