2010-06-07 3 views
0

J'ai encore un problème: D un peu d'information en premier: en essayant de copier les données d'une table vers une autre table (la structure est la même). maintenant une cellule doit être incrémentée, beginns par groupe à 1 (comme un histroy).Comptage d'une cellule par objet

i ont cette table:

create table My_Test/My_Test2 (
my_Id Number(8,0), 
my_Num Number(6,0), 
my_Data Varchar2(100)); 

(mon_id, my_Num est un PK imbriquée)

si je veux insérer une nouvelle ligne, je dois vérifier si la valeur my_id existe déjà. Si cela est vrai, je dois utiliser le my_Num suivant pour cet ID.

j'ai dans mon tableau:

My_Id My_Num My_Data 
1  1   'test1' 
1  2   'test2' 
2  1   'test3' 

si j'ajouter maintenant une ligne pour my_Id 1, la ligne ressemblera à ceci: j'ai dans mon tableau:

My_Id My_Num My_Data 
1  3   'test4' 

cela semble assez facile, maintenant je dois le faire dans un SQL et sur SQL Server j'ai eu le même problème et j'ai utilisé ceci:

Insert Into My_Test (My_Id,My_Num,My_Data) 
SELECT my_Id, 
    (
    SELECT 
     CASE (
      CASE MAX(a.my_Num) 
      WHEN NULL 
      THEN 0 
      Else Max(A.My_Num) 
      END) + b.My_Num 
     WHEN NULL 
     THEN 1 
     ELSE (
      CASE MAX(a.My_Num) 
      WHEN NULL 
      THEN 0 
      Else Max(A.My_Num) 
      END) + b.My_Num 
     END 
    From My_Test A 
    where my_id = 1 
) 
    ,My_Data 
From My_Test2 B 
where my_id = 1; 

this Select renvoie null si aucune ligne n'est trouvée dans la sous-sélection

Y a-t-il un moyen pour que je puisse utiliser max dans le cas? et si elle renvoie null, elle doit utiliser 0 ou 1?

Edit: Im usung maintenant ceci:

Insert INTO My_Test (My_Id,My_Num,My_Data) 
SELECT B.My_Id, 
    (
    SELECT COALESCE(MAX(a.My_Num),0) + b.my_Num 
    FROM My_Test A 
    Where a.My_Id = b.My_Id) 
    ,b.My_Data 
FROM My_Test2 B 
WHERE My_Id = 1 

THX à Bharat et OMG Poneys

salue
Auro

Répondre

0

Essayez celui

Insert Into My_Test (My_Id,My_Num,My_Data) 
SELECT my_Id,(
    SELECT MAX(NVL(My_Num,0)) + 1  
    From My_Test 
    where my_id = b.my_id 
) 
,My_Data 
From My_Test2 B 
where my_id = <your id>; 
+0

Cela fonctionne mais si l'ID n'existe pas dans le tableau, toutes les lignes insérées auront un 'null'. – domiSchenk

+0

Je pense que vous devez créer un ID comme clé primaire. – Bharat

+0

L'ID est un PK groupé avec my_Num – domiSchenk

0
Insert Into My_Test (My_Id,My_Num,My_Data) 
select My_id,coalesce(max(My_num),0),'test4' from My_Test 
where My_id=1 
group by My_id 
+0

Lors de la copie d'une table source vers la table de destination, si vous utilisez cette instruction, elle n'insèrera qu'un seul enregistrement dans la table de destination même s'il existe plusieurs enregistrements dans la table source. – Bharat

+0

Ensuite, vous devez supprimer la clause where – Madhivanan

0

Toutes les solutions présentent un problème en ce qu'elles ne fonctionnent pas dans un environnement multi-utilisateur. Si deux sessions émettent cette instruction insert en même temps, elles obtiendront toutes deux la même combinaison (my_id, my_num) et l'une d'entre elles échouera avec une violation de contrainte unique ORA-00001. Par conséquent, si vous avez besoin que cela fonctionne dans un environnement multi-utilisateur, le meilleur conseil est d'utiliser une seule colonne de clé primaire et de la remplir avec une séquence. Conservez également votre colonne my_id, car il s'agit d'une colonne de type de regroupement ou de colonne de clé étrangère. Si vos utilisateurs finaux aiment vraiment voir la colonne "my_num" dans leur application (web), vous pouvez utiliser la fonction analytique row_number.

Vous pouvez en savoir plus sur ce scénario dans cette blogpost de la mine: http://rwijk.blogspot.com/2008/01/sequence-within-parent.html

Cordialement, Rob .

+0

Eh bien c'est un bon point! Mais cette instruction SQL ne sera utilisée que par une seule personne, et même s'il y avait plus de sessions, elles ne fonctionneraient pas sur le même ID (l'ID est quelque chose comme l'ID d'une personne et my_Num est un historique. fusionner 2 personnes ensemble c'est la raison de compter ce nombre) - Et btw je ne suis pas autorisé à utiliser la séquence et je pense que cela ne fonctionnerait pas pour cela ou vous voulez faire une séquence pour chaque ID? Cordialement, Auro – domiSchenk

Questions connexes