2016-08-13 139 views
0

我對創建和更改SQL(Oracle)中的表相當新,並且有一個問題涉及基於其他值中的值更新一個表。根據其他表中的值更新Oracle中的列

說我有表答:

ID  Date   Status  
---  ---   --- 
1  1/1/2000  Active 
2  5/10/2007  Inactive 
2  2/15/2016  Active 
3  10/1/2013  Inactive 
4  1/11/2004  Inactive 
5  4/5/2012  Inactive 
5  6/12/2014  Active 

和表B:

ID  Date   Status  Number of Records in A 
---  ---   ---   --- 
1  
2  
3  
4  
5  

什麼是更新表B中獲得最新的每個項目和計數的日期和狀態的最好方法A的記錄?我知道我可以加入表格,但是我希望B能夠作爲自己的表格存在。

+0

這已經在這裏回答: http://stackoverflow.com/questions/7030699/oracle-sql-update-a-table-with-data-from-another-table – GavinCattell

+0

@GavinCattell - 不,它hasn 「T。您鏈接的問題與獲取每個id的最近日期和狀態沒有關係,也沒有關於id的記錄數。 – mathguy

+0

請顯示預期的輸出 – OldProgrammer

回答

0

甲骨文可以讓你在update聲明一次性分配多個列。所以,你可以這樣做:

update b 
    set (dt, status, ct) = 
     (select max(dt), 
       max(status) keep (dense_rank first order by dt desc), 
       count(*) 
      from a 
      where a.id = b.id 
     ) ; 

基本上可以使用子查詢 - 一個group by - 如果你想爲所有的ID作爲查詢結果:

select max(dt), 
     max(status) keep (dense_rank first order by dt desc), 
     count(*) 
from a 
group by id; 

您還可以使用create table asinsert into將記錄直接放入b,而不必使用update與其匹配。

0

就是這樣。如果您已經有了表B,並且您需要使用此查詢中的值填充它,或者如果您需要使用這些值創建新表B,請根據需要進行調整。注:我使用dt作爲列名,因爲「date」是Oracle中的保留字。 (出於同樣的原因,我用「克拉」爲「數」。)

with 
    table_A ( id, dt, status) as (
     select 1, to_date('1/1/2000', 'mm/dd/yyyy'), 'Active' from dual union all 
     select 2, to_date('5/10/2007', 'mm/dd/yyyy'), 'Inactive' from dual union all 
     select 2, to_date('2/15/2016', 'mm/dd/yyyy'), 'Active' from dual union all 
     select 3, to_date('10/1/2013', 'mm/dd/yyyy'), 'Inactive' from dual union all 
     select 4, to_date('1/11/2004', 'mm/dd/yyyy'), 'Inactive' from dual union all 
     select 5, to_date(' 4/5/2012', 'mm/dd/yyyy'), 'Inactive' from dual union all 
     select 5, to_date('6/12/2014', 'mm/dd/yyyy'), 'Active' from dual 
    ), 
    prep (id, dt, status, rn, ct) as (
     select id, dt, status, 
       row_number() over (partition by id order by dt desc), 
       count(*) over  (partition by id) 
     from table_A 
    ) 
select id, to_char(dt, 'mm/dd/yyyy') as dt, status, ct 
from prep 
where rn = 1 
; 


     ID DT   STATUS   CT 
---------- ---------- -------- ---------- 
     1 01/01/2000 Active   1 
     2 02/15/2016 Active   2 
     3 10/01/2013 Inactive   1 
     4 01/11/2004 Inactive   1 
     5 06/12/2014 Active   2 

新增:你剛纔提到你在這個漂亮的新...所以:例如,如果你需要創建表-B與這些結果和table_A已經存在並被填充:第一,在我的解決方案中,您不需要「table_A」分解子查詢;第二,您將創建表-B的東西,如

create table table_B as 
with 
    prep (.....) -- rest of the solution here, up to and including the ; 
+0

注意:我的解決方案和Gordon都遭受同樣的問題,但以不同的方式。如果您有相同的ID和日期有兩行或更多行,那麼要求是什麼?我的解決方案將隨機選擇一個狀態。 Gordon的解決方案將返回MAX(STATUS)按照該ID的字母順序排列的任何內容。在這種情況下,這兩種「解決方案」都可能會破壞您的業務需求 – mathguy

相關問題