基于另一个表的小计更新字段

时间:2021-01-21 23:10:02

I'm using oracle(10).

我正在使用oracle(10)。

I've got two tables as follows:

我有两张桌子如下:

Table1 (uniq rows):
ID    AMOUNT     DATE 

Table2:
ID    AMOUNT1 AMOUNT2 ...AMOUNTN DATE

Table2 is connected many to one to Table1 connected via ID.

表2通过ID连接到表1连接多对一。

What I need is update-ing Table1.DATE with: the last (earliest) date from Table2 where Table1.AMOUNT - SUM(Table2.AMOUNT1) <= 0, when reading table 2 backwards by the Table2.DATE field.

我需要的是更新Table1.DATE:表2中的最后(最早)日期,其中Table1.AMOUNT - SUM(Table2.AMOUNT1)<= 0,当Table2.DATE字段向后读表2时。

Is there a simple way to do it?

有一个简单的方法吗?

Thanks in advance!

提前致谢!

UPDATE: as I see from your answers I had misspecified the question a bit. So here goes a detailed example:

更新:正如我从你的答案中看到的那样,我错误地指出了这个问题。所以这里有一个详细的例子:

Table1 has:

ID: 1     AMOUNT:100    DATE:NULL

Table2 has (for ID: 1 so ID is not listed in here):

表2有(对于ID:1,因此ID未在此处列出):

AMOUNT1     DATE
50          20080131
30          20080121
25          20080111
20          20080101

So in this case I need 20080111 as the DATE in Table1 as 50+30+25 => 100.

所以在这种情况下,我需要20080111作为表1中的DATE,因为50 + 30 + 25 => 100。

2 个解决方案

#1


Based on your revised question, this is a case for using analytic functions.

根据您修改过的问题,这是使用分析函数的一种情况。

Assuming you meant >=100 rather than <= 100 as your example implies, and renaming columns DATE to THEDATE since DATE is a reserved word in Oracle:

假设您的意思是> = 100而不是<= 100,如您的示例所示,并将DATE列重命名为THEDATE,因为DATE是Oracle中的保留字:

update table1 set thedate=
( select max(thedate) from
  ( select id, thedate,
           sum(amount1) over (partition by id  order by thedate desc) cumsum
    from table2
  ) v
  where v.cumsum >= 100
  and v.id = table1.id
)

If the 100 means the current value of table1 then change that line to:

如果100表示​​table1的当前值,则将该行更改为:

  where v.cumsum >= table1.amount

#2


First off - your database layout feels severely wrong, but I guess you can't / don't want to change it. Table1 should probably be a view, and Table2 does not make the impression of proper normalization. Something like (ID, AMOUNT_TYPE, AMOUNT_VALUE, DATE) would make much more sense to me.

首先 - 你的数据库布局感觉严重错误,但我想你不能/不想改变它。表1可能应该是一个视图,而Table2没有给出正确规范化的印象。像(ID,AMOUNT_TYPE,AMOUNT_VALUE,DATE)这样的东西对我来说会更有意义。

But to solve your problem (this is T-SQL "UPDATE FROM" syntax, but I think Oracle knows it):

但是要解决你的问题(这是T-SQL“UPDATE FROM”语法,但我认为Oracle知道它):

UPDATE 
  Table1
SET
  Date = Table2Aggregate.MinDate
FROM
  Table1 
  INNER JOIN (
    SELECT Id, SUM(Amount1) SumAmount1, MIN(Date) MinDate 
    FROM Table2 
    GROUP BY Id
  ) AS Table2Aggregate ON Table1.Id = Table2Aggregate.ID 
WHERE
  Table1.Amount - Table2Aggregate.SumAmount1 <= 0

#1


Based on your revised question, this is a case for using analytic functions.

根据您修改过的问题,这是使用分析函数的一种情况。

Assuming you meant >=100 rather than <= 100 as your example implies, and renaming columns DATE to THEDATE since DATE is a reserved word in Oracle:

假设您的意思是> = 100而不是<= 100,如您的示例所示,并将DATE列重命名为THEDATE,因为DATE是Oracle中的保留字:

update table1 set thedate=
( select max(thedate) from
  ( select id, thedate,
           sum(amount1) over (partition by id  order by thedate desc) cumsum
    from table2
  ) v
  where v.cumsum >= 100
  and v.id = table1.id
)

If the 100 means the current value of table1 then change that line to:

如果100表示​​table1的当前值,则将该行更改为:

  where v.cumsum >= table1.amount

#2


First off - your database layout feels severely wrong, but I guess you can't / don't want to change it. Table1 should probably be a view, and Table2 does not make the impression of proper normalization. Something like (ID, AMOUNT_TYPE, AMOUNT_VALUE, DATE) would make much more sense to me.

首先 - 你的数据库布局感觉严重错误,但我想你不能/不想改变它。表1可能应该是一个视图,而Table2没有给出正确规范化的印象。像(ID,AMOUNT_TYPE,AMOUNT_VALUE,DATE)这样的东西对我来说会更有意义。

But to solve your problem (this is T-SQL "UPDATE FROM" syntax, but I think Oracle knows it):

但是要解决你的问题(这是T-SQL“UPDATE FROM”语法,但我认为Oracle知道它):

UPDATE 
  Table1
SET
  Date = Table2Aggregate.MinDate
FROM
  Table1 
  INNER JOIN (
    SELECT Id, SUM(Amount1) SumAmount1, MIN(Date) MinDate 
    FROM Table2 
    GROUP BY Id
  ) AS Table2Aggregate ON Table1.Id = Table2Aggregate.ID 
WHERE
  Table1.Amount - Table2Aggregate.SumAmount1 <= 0