updater n lignes : combler des trous

updater n lignes : combler des trous - SQL/NoSQL - Programmation

Marsh Posté le 25-07-2014 à 15:59:09    

bonjour,
je sèche sur un update à la "gomme" :)
Voici mon soucis :
Ma table , t1 (id,c1, c2, ,....) et c'est là que c'est mal foutu, j'ai  
t1(id,c1, c2)
    1,v1, x
    2,   ,y  
    3,    z
    4,v2,a    
    5,   ,b
    6,   ,c
    7,   ,x
    8,   ,z
...
   idn,vn,a1
   idn+1,  ,a2
   idn+2,  ,a3
 
...)
j'aimerai pouvoir updater mon champ c1, avec les valeurs V1 pour les id 2,3,4  , puis v2, pour les id 5,6,7,8...  
t1(id,c1, c2)
    1,v1, x
    2,v1,y  
    3,v1,z
    4,v2,a    
    5,v2,b
    6,v2,c
    7,v2,x
    8,v2,z
...
   idn,vn,a1
   idn+1,vn,a2
   idn+2,vn,a3
...)
 
Je séche, j'arrive pas à me dépétrer... sans y perdre trop de temps... :)
Si quelqu'un a une bonne idée... :)
j'ai pensé à des cursors, à excel aussi...
 
D'avance, merci et bon weekend...  
Guillaume


Message édité par gpl73 le 25-07-2014 à 16:21:37

---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 25-07-2014 à 15:59:09   

Reply

Marsh Posté le 25-07-2014 à 16:16:19    

déjà y'a contradiction entre ta règle et ton exemple
dans ton exemple, la ligne 4 donne : 4,v2,a
alors que la règle énoncée donne 4,v1,a
 
déjà faut dire la quelle des solutions est bonne
après ça doit pouvoir se faire par requête, mais avec des sous select

Reply

Marsh Posté le 25-07-2014 à 16:24:30    

oui, désolé, je viens de modifier la régle... c'est vraiement de combler les trous... comme dans l'exemple...
la ligne 4,v2,2  ne doit pas "bouger" , comme toutes les lignes ayant une valeur c1 non vide...
= ligne de référence, pour les lignes dont l'id est superieur...jusqu'à la prochaine ...


---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 25-07-2014 à 16:29:47    

update t1 set c1 =  
( select c1 from t1 t2  
  where t2.id < t1.id  
  and t2.c1 is not null
  and t2.id = ( select max(t3.id) from t1 t3
                     where t3.id < t1.id and c1 is not null ))
where t1.c1 is null
 
après ça dépend de ta base de donnée. ça sera à réécrire peut être pour s'y adapter.

Reply

Marsh Posté le 25-07-2014 à 16:30:00    

SELECT t1.id, (SELECT MAX(t2.c1) FROM table t2 WHERE t2.id<t1.id) AS c1
FROM table t1
WHERE t1.c1 IS NULL;

Un peu moche mais ca devrait te donner toutes les paires (id, c1) a updater - si et seulement si tes valeurs de c1 sont "rangees" dans le meme ordre que tes id bien sur, sinon le coup du MAX(t2.c1) ne donnera pas la bonne valeur.
 
Apres a toi de foutre ca dans un MERGE; la syntaxe depend de ton SGBD.
Genre pour Oracle, un truc dans le genre:

MERGE INTO table t_updated
USING (
  SELECT t1.id, (SELECT MAX(t2.c1) FROM table t2 WHERE t2.id<t1.id) AS c1
  FROM table t1
  WHERE t1.c1 IS NULL) t_valeurs ON (t_updated.id = t_valeurs.id)
WHEN MATCHED THEN UPDATE SET t_updated.c1 = t_valeurs.c1;

Evidemment, pas teste etc.


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 25-07-2014 à 16:35:08    

ok ;)
je vais voir ça...
merci


---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 28-07-2014 à 12:58:02    

Essaye ca (SQL Server):

Code :
  1. Declare @PreviousC1 varchar(20)
  2. SET @PreviousC1 = ''
  3.  
  4. UPDATE T1
  5.     SET @PreviousC1 = C1 = CASE WHEN @PreviousC1 != C1 THEN C1 ELSE @PreviousC1 END


 
Ton cluster index doit être sur ID.
Ca scale super bien, 3 sec pour 1 million de rows, et ca ne fait qu'un seul table scan.

Reply

Marsh Posté le 28-07-2014 à 13:25:34    

merci à tous ...
J'ai pris celui de ddr555 , car c'est celui qui me plaisait le mieux ! Le plus simple à "pomper" :)... Nickel !
Je garde sous le coude les autres propositions quand même pour d'autres cas...
Guillaume


Message édité par gpl73 le 28-07-2014 à 13:42:49

---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed