2017-07-10 4 views
1

Il est difficile d'expliquer correctement la question dans le titre.Insérer la valeur basée sur la valeur minimale supérieure à la valeur dans une autre ligne

J'insère 6 valeurs de (ou basées sur des valeurs dans) une ligne. je besoin aussi d'insérer une valeur à partir d'une seconde rangée où:

  1. Les valeurs dans une colonne (ID) doivent être égaux
  2. Les valeurs dans la colonne (CODE) dans la ligne principale source doit être dans le (100,200), tandis que l'autre ligne doit avoir la valeur 300 ou 400
  3. La valeur dans une autre colonne (OBJID) dans la ligne secondaire doit être la valeur la plus basse au-dessus de celle de la ligne principale.

Table Source ressemble:

OBJID | CODE | ENTRY_TIME | INFO | ID | USER 
--------------------------------------------- 
    1 | 100 | x timestamp| .... | 10 | X 
    2 | 100 | y timestamp| .... | 11 | Y 
    3 | 300 | z timestamp| .... | 10 | F 
    4 | 100 | h timestamp| .... | 10 | X 
    5 | 300 | g timestamp| .... | 10 | G 

Donc, pour donner un exemple .. Dans ma deuxième table, je veux insérer OBJID, OBJID2, CODE, ENTRY_TIME, substr(INFO(...)), ID, USER

Par exemple, à partir de mon exemple, une ligne insérée dans la deuxième table ressemblerait à:

OBJID | OBJID2 | CODE | ENTRY_TIME | INFO  | ID | USER 
----------------------------------------------------------- 
    1 | 3 | 100 | x timestamp| substring | 10 | X 
    4 | 5 | 100 | h timestamp| substring2| 10 | X 

Mon insertion pour tout ce qui vient juste d'une rangée fonctionne bien.

INSERT INTO TABLE2 
(ID, OBJID, INFO, USER, ENTRY_TIME) 
SELECT ID, OBJID, DECODE(CODE, 100, (SUBSTR(INFO, 12, 
LENGTH(INFO)-27)),               
600,'CREATE') INFO, USER, ENTRY_TIME 
FROM TABLE1 
WHERE CODE IN (100,200); 

Je suis conscient que je vais avoir besoin d'utiliser un alias sur TABLE1, mais je ne sais pas comment le reste de travailler, en particulier d'une manière efficace. Il y a actuellement 2 millions de lignes, mais il y en aura près de 20 millions une fois que je commencerai à utiliser les données de production.

+0

mieux que de vous donner une solution ici, je vous suggère de créer une vue, où mettre tous vous logique et obtenir le résultat attendu de la façon dont vous le voulez. Exécutez ensuite l'instruction d'insertion en tant que sélection dans cette nouvelle vue. – g00dy

+0

Pouvez-vous compléter la table de sortie pour nous? S'il vous plaît, donnez-nous toutes les lignes pour cela. Il est difficile de comprendre ce que vous voulez des spécifications actuelles. –

+0

@FlorinGhita Si je pouvais compléter le tableau de sortie alors je n'aurais pas besoin de poser la question en premier lieu. À partir des lignes d'exemple que j'ai données dans la première table, il n'y a qu'une seule ligne complète possible dans la deuxième table. – Slingy

Répondre

2

Vous pouvez essayer ceci:

select primary.* , 
    (select min(objid) 
    from table1 secondary 
    where primary.objid < secondary.objid 
     and secondary.code in (300,400) 
     and primary.id = secondary.id 
    ) objid2 
from table1 primary 
where primary.code in (100,200); 
+0

Des alias étranges, mais une belle solution! :) –

0

Ok, je suis venu avec:

select OBJID, 
     min(case when code in (300,400) then objid end) 
      over (partition by id order by objid 
       range between 1 following and unbounded following 
       ) objid2, 
     CODE, ENTRY_TIME, INFO, ID, USER1 
from table1; 

, vous avez besoin d'une insert select la requête ci-dessus avec un where objid2 is not null et code (100200);