4

J'ai la structure de tableau suivante.Utilisation de CTE au lieu du curseur

Je veux juste mettre à jour subid à toutes les lignes où elle est nulle et où le RawLineNumber est ascendante par 1 et aussi le SeqNumber croissant par 1.

RawlineNumber Claimid SubId SeqNumber 
1    6000 A100 1 
2    6000 NULL 2 
3    6000 NULL 3 
10   6000 A200 1 
11   6000 NULL 2 
25   6000 A300 1 
26   6000 NULL 2 
27   6000 NULL 3 

Je veux mettre à jour
subid de RawLineNumber 2 et 3 avec A100,
Su Bid de RawLineNumber 11 avec A200,
subid de RawLineNumber 26 et 27 avec A300.

J'ai un curseur qui fait le travail mais puis-je avoir un CTE pour m'en occuper?

Répondre

7
UPDATE m 
SET  subid = q.subid 
FROM mytable m 
CROSS APPLY 
     (
     SELECT TOP 1 subid 
     FROM mytable mi 
     WHERE mi.rawLineNumber < m.rawLineNumber 
       AND mi.subid IS NOT NULL 
     ORDER BY 
       rawLineNumber DESC 
     ) q 
WHERE m.subid IS NULL 
+0

1 - Nice. Je ne pense jamais à utiliser «CROSS APPLY» pour des choses comme ça. – JNK

+0

Je suis juste nouveau pour être 'CROSS APPLY'. Pouvez-vous pls laissez-moi savoir quel champ vous utilisez comme' id' ici. –

+1

Je pense qu'il veut dire RawlineNumber – Aducci

0

Un pas si simple script SQL doit obtenir ce que vous voulez:

update my_table t1 set t1.subid = 
    (select t2.subid from my_table t2 
    where t2.rawlinenumber < t1.rawlinenumber 
    and t2.seqnumber = 1 
    and t2.rawlinenumber = (
        select max(t3.rawlinenumber) 
        from my_table t3 
        where t3.seq_number = 1 
        and t3.rawlinenumber <= t2.rawlinenumber) 
where t1.subid is null; 

Le subselect intérieur (T3) nous donne la dernière ligne ayant SeqNumber = 1 avant la ligne courante, le subselect extérieur nous donne la SubID pour cette ligne (en utilisant les fonctions de fenêtrage serait plus efficace, mais comme vous ne l'avez pas mentionné un SGBDR spécifique, je bâton avec cette :-))

+0

j'utilise SQLServer 2005 BTW .. –

2

depuis une solution recusive a été demandé, j'ai décidé de écris-en un. En outre, il travaille pour des lacunes dans Seqnumbers et RawlineNumber

declare @t table (RawlineNumber int, Claimid int, SubId varchar(5), SeqNumber int) 

insert @t values(1, 6000, 'A100', 1) 
insert @t values(2, 6000, NULL, 2) 
insert @t values(3, 6000, NULL, 3) 
insert @t values(10, 6000, 'A200', 1) 
insert @t values(11, 6000, NULL, 2) 
insert @t values(25, 6000, 'A300', 1) 
insert @t values(26, 6000, NULL, 2) 
insert @t values(27, 6000, NULL, 3) 

;with cte as 
(
select Rawlinenumber, SeqNumber, SubId 
from @t where SubId is not null and SeqNumber = 1 
union all 
select t.Rawlinenumber, t.SeqNumber, c.SubId 
from cte c 
join 
@t t 
on c.Rawlinenumber + 1 = t.Rawlinenumber 
and c.SeqNumber + 1 = t.SeqNumber 
where t.SubId is null and t.SeqNumber > 1 
) 
update t 
set SubId = c.SubId 
from @t t join cte c 
on c.Rawlinenumber = t.Rawlinenumber 
where t.SeqNumber > 1 

select * from @t 
+0

Merci pour cela. Dans mon scénario il n'y aura pas de lacunes dans seq et RawLineNumber.so n'a pas testé pour ces scénarios ... donc la solution de Quassnoi fonctionne bien. –

Questions connexes