обновить поле на основе промежуточного итога из другой таблицы - PullRequest
0 голосов
/ 13 января 2009

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

У меня есть две таблицы:

Table1 (uniq rows):
ID    AMOUNT     DATE 

Table2:
ID    AMOUNT1 AMOUNT2 ...AMOUNTN DATE

Таблица2 подключена много к одному к Таблице1, подключенной через ID.

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

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

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

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

Таблица1 имеет:

ID: 1     AMOUNT:100    DATE:NULL

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

AMOUNT1     DATE
50          20080131
30          20080121
25          20080111
20          20080101

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

Ответы [ 2 ]

4 голосов
/ 13 января 2009

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

Предполагается, что вы имели в виду> = 100, а не <= 100, как предполагает ваш пример, и переименовывает столбцы DATE в THEDATE, поскольку DATE является зарезервированным словом в Oracle: </p>

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 означает текущее значение таблицы1, измените эту строку на:

  where v.cumsum >= table1.amount
0 голосов
/ 13 января 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
...