![](/img/trans.png)
[英]In Oracle PL/SQL can I swap the value of the same column of two differents rows in a table when the rest of the values of the columns are equal?
[英]Swap values for two rows in the same table in SQL Server
我想交换表中两行的值。 我有两行的行 ID。 有什么查询可以做到这一点吗? 这是一个例子。 在查询之前我有这个:
row1 : 1,2,3 row2 : 5,6,7
交换后我想要这个:
row1 : 5,6,7 row2 : 1,2,3
如果要将两个已知 ID 的值从一行交换到另一行,请尝试以下操作:
--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)
简单的更新工作:
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
结果:行值被交换。
如果您只需要交换几行,那么是的,您可以使用量身定制的 case 语句和连接语句来强制执行它,就像在其他答案中一样。 但是如果你需要对多行进行操作,那将会很痛苦。
WITH map AS (
SELECT *
FROM (VALUES
(1, 2), -- Here's an example of swapping two rows:
(2, 1), -- 1 <- 2, 2 <- 1
(3, 4), -- Here's an example of rotating three rows:
(4, 5), -- 3 <- 4, 4 <- 5, 5 <- 3
(5, 3),
(6, 7) -- Here's 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
笔记
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')
您不一定需要使用表的 ID 列,我相信您可以使用适当的连接逻辑按任何列进行搜索。 将桌子连接到自己是诀窍。
我最近遇到了类似的问题,我有一个用于订购输出的列,并希望允许移动订单。 我正在寻找答案并遇到了这个问题。 这并没有充分回答我的特定查询,但也许我的解决方案会帮助其他人。
我的数据库看起来像这样
表:订单_表
Index_Column,Order_Column,Text
1 ,1 ,"Second Test text"
2 ,2 ,"First Test text"
我希望能够在 php 中使用 pdo 来交换它们。 最终我找到了一种使用 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)
您需要通过“WHERE”条件选择所有记录,然后通过“CASE”条件“SET”更新。
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);
以上示例均不实用......它应该类似于以下更新部分:
/*******************************************************************************/
/* 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
如果它只是一个必须在两行之间交换的值:
UPDATE task t1 SET ordre = (SELECT ordre FROM task t2 WHERE t1.id <> t2.id AND id IN (26,25)) WHERE id IN (26,25)
UPDATE Salary SET sex = CASE WHEN sex ='m' THEN 'f' ELSE 'm' END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.