Обмен значениями для двух строк в одной таблице в SQL Server

Я хочу поменять местами значения из двух строк в таблице. У меня есть идентификаторы строк двух строк. Есть ли запрос, чтобы сделать это? Вот пример. Перед запросом у меня есть это:

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

После обмена я хочу это:

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

Ответ 1

Если вы хотите поменять значения из одной строки в другую для двух известных идентификаторов, попробуйте что-то вроде этого:

--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)

Ответ 2

Простое обновление работает:

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 

Результат: значения строк меняются местами.

Ответ 3

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')

Вам необязательно использовать столбец идентификатора вашей таблицы, я считаю, что вы можете искать любой столбец с соответствующей логикой соединения. Соединение таблицы с самим собой - это трюк.

Ответ 4

У меня была аналогичная проблема, недавно у меня был столбец для заказа вывода и я хотел разрешить перемещение порядка. Я искал ответ и столкнулся с этим вопросом. Это не удовлетворило мой конкретный запрос, но, может быть, мое решение поможет другим.

У меня была моя база данных так:

Таблица: Order_Table

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

Я хотел иметь возможность обменивать их с помощью pdo в php. В конечном итоге я нашел способ сделать это с помощью одного 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)

Ответ 5

Вам нужно выбрать все записи по условию "ГДЕ", Затем "SET" обновляется по условию "CASE".

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);

Ответ 6

Ни один из приведенных выше примеров не является практичным... Он должен выглядеть следующим образом:

/*******************************************************************************/
/*  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

Ответ 7

Если вам нужно поменять местами только пару строк, то да, вы можете грубо форсировать его с помощью специальных инструкций case и объединять операторы, как в других ответах. Но если вам нужно работать на нескольких рядах, это будет боль.

Простое масштабируемое решение

WITH map AS (
    SELECT *
    FROM (VALUES
        (1, 2),  -- Here an example of swapping two rows:
        (2, 1),  -- 2 <- 1,  1 <- 2

        (3, 4),  -- Here an example of rotating three rows:
        (4, 5),  -- 3 <- 4,  4 <- 5,  5 <- 3
        (5, 3),

        (6, 7)   -- Here an example of just copying one row to another: 3 <- 5
    ) AS a (destID, srcID)
)
UPDATE destination
SET
    ColumnA = source.ColumnA,
    ColumnB = source.ColumnB,
    ColumnC = source.ColumnC
FROM
    SomeTable AS destination
    JOIN map ON map.destID = destination.ID
    JOIN SomeTable AS source ON source.ID = map.srcID

Заметки

  • Вы можете делать двухрядные, многострочные и копирование. Это гибкий.
  • Укажите столько пар строк назначения/источника, сколько необходимо. Будут обновлены только строки назначения.
  • Укажите столбцы, которые вы хотите скопировать. Только эти столбцы будут обновлены.
  • Там нет временного стола для очистки.
  • Его легко использовать повторно, поскольку идентификаторы строк перечислены в одном очевидном месте.

Ответ 8

Я создал одну таблицу с именами столбцов и пол. Я вставил в него значения. Теперь я хочу обменять значения в столбце пола как M = F, F = M.