2009-01-13 18 views
0

J'utilise oracle (10).mettre à jour un champ basé sur le sous-total d'une autre table

J'ai deux tables comme suit:

Table1 (uniq rows): 
ID AMOUNT  DATE 

Table2: 
ID AMOUNT1 AMOUNT2 ...AMOUNTN DATE 

Tableau2 est connecté à plusieurs à un tableau 1 connecté via ID. Ce dont j'ai besoin, c'est de mettre à jour Table1.DATE avec: la dernière (date la plus ancienne) de Table2 où Table1.AMOUNT - SUM (Table2.AMOUNT1) < = 0, lors de la lecture de la table 2 vers l'arrière par le champ Table2.DATE .

Existe-t-il un moyen simple de le faire?

Merci d'avance!

MISE À JOUR: comme je vois de vos réponses j'avais mal spécifié la question un peu. Alors, voici un exemple détaillé:

Tableau 1 a:

ID: 1  AMOUNT:100 DATE:NULL 

Tableau2 a (pour ID: 1 pour ID ne figure pas ici):

AMOUNT1  DATE 
50   20080131 
30   20080121 
25   20080111 
20   20080101 

Donc dans ce cas je besoin 20080111 comme le DATE dans le tableau1 comme 50 + 30 + 25 => 100.

+0

Pourquoi ne pas fournir de créer des scripts de table? Cela rend beaucoup plus facile de répondre à votre question. Et pourquoi appelez-vous une colonne «date»? Vous ne pouvez pas créer de table avec un nom de colonne appelé "date". – tuinstoel

+0

50 + 30 + 25> = 100 – tuinstoel

+0

Je suis d'accord avec tuinstoel, votre question est très vaguement exprimée et difficile à suivre. Au début, vous avez dit <= 0, alors dans votre exemple <= 100. Voulez-vous en fait dire <= (or > =) table1.amount? –

Répondre

4

Basé sur votre question révisée, ceci est un cas d'utilisation de fonctions analytiques.

En supposant que vous vouliez dire> = 100 plutôt que < = 100 comme par exemple l'indique, et les colonnes changement de nom DATE à theDate depuis DATE est un mot réservé dans 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 
) 

Si les 100 signifie que la valeur actuelle de table1 puis changez cette ligne à:

where v.cumsum >= table1.amount 
+0

Merci pour votre aide Tony, s'il vous plaît noter que je ne suis pas un programmeur, j'ai obtenu seulement un diplôme en finance, et j'ai beaucoup appris de gars comme vous puisque je dois travailler avec le support logiciel bancaire ... Vous m'aviez beaucoup aidé - si seulement quelqu'un pouvait expliquer avec des mots simples comment ça fonctionnait ;-) –

0

Tout d'abord - votre mise en page de base de données se sent sévèrement mal, mais je suppose que vous ne pouvez pas/ne veulent pas changer. Table1 devrait probablement être une vue, et Table2 ne fait pas l'impression d'une normalisation correcte. Quelque chose comme (ID, AMOUNT_TYPE, AMOUNT_VALUE, DATE) me ferait beaucoup plus de sens.

Mais pour résoudre votre problème (ce qui est T-SQL "UPDATE FROM" syntaxe, mais je pense que Oracle le sait):

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 
+0

J'avais édité la question avec un exemple plus détaillé car la tienne était une bonne solution, sauf le cas d'avoir beaucoup de SOMME (Montant1) dans le tableau 2 - comme cela trouve la toute dernière date que je vois ... –