2009-09-20 8 views
2

Si j'ai ces données dans un tableau en MSSQL qui représente une ligne horizontale d'objets et de leurs coordonnées:données Réorganiser dans une table

row  id  value 
35395 776130 0 
35395 776131 20 
35395 776132 40 
35395 776133 60 
35395 776134 80 
35395 776135 100 
35395 776136 120 
35395 776137 140 
35395 776138 160 
35395 776139 180 
35395 776140 200 

Et je veux changer les valeurs de sorte qu'ils sont ordonnés en ordre descendant ordre (retourner les 180 degrés de ligne):

row  id  value 
35395 776130 200 
35395 776131 180 
35395 776132 160 
35395 776133 140 
35395 776134 120 
35395 776135 100 
35395 776136 80 
35395 776137 60 
35395 776138 40 
35395 776139 20 
35395 776140 0 

Comment puis-je faire cela en utilisant une déclaration de mise à jour sans le faire un par un?

Répondre

0

Avec l'aide de Seb's answer je formulé une solution:

declare @maxcoord int; 
declare @rowid int; set @rowid = 35395 

select @maxcoord = max(value) from table where row = @rowid 

update table set value = @maxcoord - value 
where row = @rowid 

Je pense que je vais créer une procédure stockée pour ce que je ne pense pas que ce sera la seule fois où il sera utilisé :)

+0

Les corrections de données sont une chose; Je suis curieux de connaître la logique métier derrière cela car le modèle de données ne semble pas approprié. –

+0

C'est un correctif de données. –

2

Je ne connais pas la nature du problème, mais seulement en fonction de votre exemple, vous ne pouvez pas mettre à jour toutes les lignes faisant

UPDATE `thetable` SET value = 200 - value 

Encore une fois, je ne sais pas la nature du problème afin Ce n'est peut-être pas si simple, mais cela semble fonctionner dans votre exemple simplifié et pourrait aussi bien fonctionner dans votre problème du monde réel.

+0

Merci. Je suppose que je pourrais essayer de calculer la valeur de coordonnées maximale et l'utiliser à la place de votre valeur de 200. Cela peut être la solution –

+0

Pour chaque ligne que je veux dire. Par exemple, la ligne que j'ai fournie - la valeur maximale est 200. –

+1

Cette réponse suppose bien sûr que les valeurs sont uniformément espacées – MartW

0

Si vous utilisez SQL Server 2005 ou version ultérieure, cela peut être fait pour vous. L'avantage est que c'est une seule requête.

with T1(rn,row,id,value) as (
    select 
    rank() over (
     order by value,row,id 
    ), 
    row,id,value 
    from T 
), T2(rn,value) as (
    select 
    row_number() over (
     order by value desc 
    ), value 
    from T 
), T12(row,id,value,vnew) as (
    select row,id,T1.value,T2.value 
    from T1 join T2 on T1.rn = T2.rn 
) 
    update T12 set 
    value = vnew; 

Je supposais la colonne « valeur » est de plus en plus à l'origine, et que vous voulez qu'il baisse, mais je laissais la possibilité de deux valeurs consécutives étant les mêmes, tant que (ligne, id) est une clé pour la table.

Il existe d'autres possibilités. Par exemple, si (row, id) est une clé et que vous voulez inverser l'ordre des valeurs de "value" de n'importe quelle position à la position "mirror", vous pouvez le faire:

with T1(rn,row,id,value) as (
    select 
    rank() over (
     order by row,id 
    ), 
    row,id,value 
    from T 
), T2(rn,value) as (
    select 
    rank() over (
     order by row desc,id desc 
    ), value 
    from T 
), T12(row,id,value,vnew) as (
    select row,id,T1.value,T2.value 
    from T1 join T2 on T1.rn = T2.rn 
) 
    update T12 set 
    value = vnew; 

Avec les bons index, cela pourrait être relativement efficace.

+0

Cela semble vraiment déroutant. –

0

Voulez-vous réellement mettre à jour les lignes, ou voulez-vous simplement les afficher dans l'ordre inverse? Si c'est juste l'ordre d'affichage, essayez ceci:

SELECT row, id, 200-value as Value 
    FROM YourTable 
ORDER BY (200-value) DESC 
Questions connexes