2016-08-13 88 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

相关问题