2010-05-03 5 views
9

J'ai une table et je souhaite permuter les valeurs de deux lignes. J'ai les identifiants de rangées des deux rangées. Y at-il une requête pour le faire? Voici un exemple. Avant la requête que j'ai ceci:Échange de valeurs pour deux lignes dans la même table dans SQL Server

 
row1 : 1,2,3 
row2 : 5,6,7 

Après l'échange, je veux ceci:

 
row1 : 5,6,7 
row2 : 1,2,3 

Je ne veux pas écrire dans le code .NET parce que je pense qu'une requête SQL est plus facile que cela.

+0

La première fois que je lis votre question, je pensais que vous vouliez faire une copie d'une ligne , mais maintenant je commence à penser que vous voulez mettre à jour les valeurs dans une rangée pour égaler les valeurs dans une autre rangée ... mais je ne comprends pas la partie 'vice versa' de votre question. Pouvez-vous donner quelques exemples pour clarifier votre question? –

+0

vice versa signifie ici que j'ai besoin aussi de mettre à jour la ligne que je pris des données à partir avec les données de ligne mise à jour exemple: row1: 1,2,3 row2: 5,6,7 après que je veux faire face row1: 5,6,7 row2: 1,2,3 J'espère que vous l'avez compris. –

+0

@AmRoSH: J'ai réécrit votre question pour qu'elle soit plus facile à comprendre. J'espère que je l'ai fait correctement, sinon veuillez le modifier à nouveau. Et vous devriez essayer de vous écrire clairement la question à l'avenir - il vous obtiendra des réponses de meilleure qualité plus rapidement. –

Répondre

6

Si vous souhaitez échanger des valeurs d'une rangée à l'autre pour deux ID connus essayer quelque chose comme ceci:

--need to store the original values 
SELECT 
    *,CASE WHEN id=123 then 987 ELSE 123 END AS JoinId 
    INTO #Temp 
    FROM YourTable 
    WHERE ID in (123,987) 

--swap values 
UPDATE y 
    SET col1=t.col1 
     ,col2=t.col2 
    FROM YourTable  y 
     INNER JOIN #Temp t ON y.id =t.JoinId 
    WHERE ID in (123,987) 
+0

Merci KM est cette requête fonctionne avec plusieurs lignes signifie si ces ID sont des clés forign et j'ai besoin d'échanger leurs lignes. –

+0

cela devrait fonctionner si les colonnes à échanger sont des clés étrangères ou simplement des données simples. –

+0

Est-ce que cela fonctionne avec la clé primaire? –

1

Je crée une table avec des colonnes nom et le sexe. J'ai inséré des valeurs dedans. Maintenant, je veux échanger les valeurs dans la colonne de genre comme M = F, F = M.

2

simple mise à jour fonctionne:

UPDATE myTable 
SET 
col1 = CASE WHEN col1 = 1 THEN 5 ELSE 1 END, 
col2 = CASE WHEN col2 = 2 THEN 6 ELSE 2 END, 
col3 = CASE WHEN col3 = 3 THEN 7 ELSE 3 END 

Résultat: les valeurs de ligne sont permutées.

1

J'ai eu un problème similaire récemment j'ai eu une colonne pour commander la sortie et je voulais permettre de déplacer l'ordre autour. Je cherchais la réponse et j'ai traversé cette question. Cela n'a pas suffisamment répondu à ma requête, mais peut-être que ma solution aidera les autres.

j'avais l'air ma base de données comme si

Tableau: Order_Table

Index_Column,Order_Column,Text 
1   ,1   ,"Second Test text" 
2   ,2   ,"First Test text" 

Je voulais pouvoir les échanger autour de l'utilisation pdo en php. En fin de compte, je trouve un moyen de le faire avec une requête SQL

UPDATE `Order_Table` AS o 
INNER JOIN (SELECT `Index_Column`, `Order_Column` FROM `Order_Table` 
WHERE `Index_Column` IN (:Index1,:Index2)) 
AS t ON o.`Index_Column` <> t.`Index_Column` 
SET o.`Order_Column` = t.`Order_Column` 
WHERE o.`Index_Column` IN (:Index1,:Index2) 
2
UPDATE t1 
SET 
t1.col1 = t2.col1 
,t1.col2 = t2.col2 
,t1.col3 = t2.col3 
,t1.col4 = t2.col4 
--and so forth... 
FROM YourTable AS t1 
INNER JOIN YourTable AS t2 
    ON  (t1.ID = '1' 
      AND t2.ID = '2') 
     OR 
      (t1.ID = '2' 
      AND t2.ID = '1') 

Vous ne devez pas nécessairement utiliser la colonne ID de votre table, je crois que vous pouvez rechercher par une colonne, avec le bon rejoindre la logique. Rejoindre la table à elle-même est l'astuce.

+0

est-ce possible d'échanger tout cru si je mets à jour une seule colonne en utilisant votre requête. ? Parce que je viens de mettre à jour une seule colonne en utilisant votre requête et sa permutation de la ligne entière. – FullStack

1

Vous devez sélectionner tous les enregistrements par "WHERE" condition, Ensuite, "SET" mise à jour par "CAS" condition.

UPDATE tbl_Temp SET 
fk_userType = CASE fk_userType WHEN 1 THEN 2 WHEN 2 THEN 1 END, 
fk_userRole = CASE fk_userRole WHEN 1 THEN 2 WHEN 2 THEN 1 END 
WHERE (fk_userType = 1 AND fk_userRole = 1) OR (fk_userType = 2 AND fk_userRole = 2); 
0

Aucun des exemples ci-dessus est pratique ... Il devrait ressembler à la section de mise à jour suivante:

/*******************************************************************************/ 
/* DATA TABLE IS PREPARING             */ 
/*******************************************************************************/ 
IF EXISTS (SELECT TOP 1 * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TEST' AND TABLE_SCHEMA = 'dbo') 
DROP TABLE [dbo].[TEST]; 

CREATE TABLE [dbo].[TEST](
    [ID]  int   IDENTITY(1,1) NOT NULL, 
    [Name]  varchar(50) NULL, 
    [Surname] varchar(50) NULL, 
    [AGE]  int   NULL, 
    CONSTRAINT [PK_TEST] PRIMARY KEY CLUSTERED 
    ([ID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
/*******************************************************************************/ 
/* INSERTING TEST VALUES              */ 
/*******************************************************************************/ 
INSERT INTO dbo.TEST (Name, Surname, AGE) 
SELECT 'Sevim'  , 'PARLAYAN' , 36 UNION ALL 
SELECT 'Uğur'   , 'PARLAYAN' , 41 UNION ALL 
SELECT 'Berkan Cahit' , 'PARLAYAN' , 17 UNION ALL 
SELECT 'Miray Çağla' , 'PARLAYAN' , 6 ; 

SELECT * FROM dbo.TEST ORDER BY ID; 


-- At this point maybe the trigger can be disabled... 

/*******************************************************************************/ 
/* I'm swapping Uğur and Sevim rows (So, rows into 1 and 2 do swapping)... */ 
/*******************************************************************************/ 
UPDATE TT 
SET  TT.Name  = ZZZ.Name 
    , TT.Surname = ZZZ.Surname 
    , TT.AGE  = ZZZ.AGE 
FROM  dbo.TEST as TT 
JOIN  (
      SELECT TOP 1 * FROM dbo.TEST WHERE ID = 2 /* Big key value first  */ UNION ALL 
      SELECT TOP 1 * FROM dbo.TEST WHERE ID = 1 /* Then small key value... */ 
     ) as ZZZ on ZZZ.ID in (1, 2) 
WHERE TT.ID in (1, 2) ; 

-- At this point maybe the trigger can be activated... 

SELECT * FROM dbo.TEST ORDER BY ID 
Questions connexes