обновить поле на основе промежуточного итога из другой таблицы

Я использую оракул (10).

У меня есть две таблицы следующим образом:

Table1 (uniq rows):
ID    AMOUNT     DATE 

Table2:
ID    AMOUNT1 AMOUNT2 ...AMOUNTN DATE

Table2 подключен много к одному к Table1, подключенному через ID.

Мне нужно обновить Table1.DATE с помощью: последней (самой ранней) даты из Table2, где Table1.AMOUNT - SUM(Table2.AMOUNT1) ‹= 0, при чтении таблицы 2 назад по полю Table2.DATE.

Есть ли простой способ сделать это?

Заранее спасибо!

ОБНОВЛЕНИЕ: как я вижу из ваших ответов, я немного неправильно определил вопрос. Итак, вот подробный пример:

В таблице 1 есть:

ID: 1     AMOUNT:100    DATE:NULL

В таблице 2 есть (для идентификатора: 1, поэтому идентификатор здесь не указан):

AMOUNT1     DATE
50          20080131
30          20080121
25          20080111
20          20080101

Итак, в этом случае мне нужно 20080111 в качестве ДАТЫ в таблице 1 как 50+30+25 => 100.


person Zsolt Botykai    schedule 13.01.2009    source источник
comment
Почему вы не предоставляете скрипты для создания таблиц? Так намного проще ответить на ваш вопрос. И почему вы называете столбец «датой»? Вы не можете создать таблицу с именем столбца «дата».   -  person tuinstoel    schedule 13.01.2009
comment
Я согласен с tuinstoel, ваш вопрос сформулирован очень расплывчато и за ним трудно уследить. Сначала вы сказали ‹= 0, затем в вашем примере ‹= 100. Вы на самом деле имеете в виду ‹= (или ›=) table1.amount?   -  person Tony Andrews    schedule 13.01.2009


Ответы (2)


Исходя из вашего пересмотренного вопроса, это случай использования аналитических функций.

Предполагая, что вы имели в виду >=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
)

Если 100 означает текущее значение table1, измените эту строку на:

  where v.cumsum >= table1.amount
person Tony Andrews    schedule 13.01.2009
comment
Спасибо за вашу помощь, Тони, обратите внимание, я не программист, получил только финансовое образование и многому научился у таких ребят, как вы, так как мне приходится работать с поддержкой банковского программного обеспечения... Вы мне очень помогли - если бы только кто-то мог бы объяснить простыми словами, как это работает ;-) - person Zsolt Botykai; 13.01.2009

Во-первых, ваш макет базы данных кажется очень неправильным, но я думаю, вы не можете/не хотите его менять. Table1, вероятно, должно быть представлением, а Table2 не производит впечатления правильной нормализации. Что-то вроде (ID, AMOUNT_TYPE, AMOUNT_VALUE, DATE) имело бы для меня гораздо больше смысла.

Но чтобы решить вашу проблему (это синтаксис 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
person Tomalak    schedule 13.01.2009
comment
Я отредактировал вопрос с более подробным примером, так как ваше решение было почти хорошим, за исключением случая, когда в таблице 2 было много SUM (Amount1) - так как это находит самую последнюю дату, как я вижу... - person Zsolt Botykai; 13.01.2009