交换一行内的列值



>我试图只在一行内交换两列。

例如,我们有这样一个表:

Table T:
row #    A  |  B  |  C
---------------
1      1  |  2  |  3
2      5  |  4  |  6
3      7  |  8  |  9

我正在尝试交换第 #2 行中的两个值,我想在不影响其他列的情况下将5, 4, 6更改为4, 5, 6。结果应该是这样的:

Table T:
row #    A  |  B  |  C
---------------
1      1  |  2  |  3
2      4  |  5  |  6
3      7  |  8  |  9

我应该使用 SQL 做什么?

跟进:

当我想在一行内排序时,就会提出这个问题。A,B,C可以被视为组成三角形的三个点。为了避免重复,我想将A,B,C按从小到大的顺序排序。这就是为什么我问如何在不影响其他行的情况下交换行中的值。

现在我确实找到了对数字进行排序的方法,但使用蛮力UNION并在每种情况下重命名结果,例如当A > B > CB > A > C等。

运行以下查询:

SELECT 
CASE WHEN ROW_NUMBER() over () = 2 THEN T.B ELSE T.A END AS A1,
CASE WHEN ROW_NUMBER() over () = 2 THEN T.A ELSE T.B END AS B2,
T.C
FROM T;

返回预期结果:

A  |  B  |  C
---------------
1      1  |  2  |  3
2      5  |  4  |  6
3      7  |  8  |  9

注意:这不会更改数据库中的数据。相反,它只是以不同的方式显示数据。

--

更新:以下沙盒中的完整工作示例:

https://www.db-fiddle.com/f/vYiCubo6CHMayqsjvzo5nD/4

如果你安装了 intarray 扩展,这很容易:

update t
set a = (sort(array[a,b,c]))[1],
b = (sort(array[a,b,c]))[2],
c = (sort(array[a,b,c]))[3]
;

试试这个:

UPDATE tablename
SET
A = LEAST(A, B, C),
C = GREATEST (A, B, C),
B = CASE 
WHEN A > LEAST(A, B, C) AND A < GREATEST (A, B, C) THEN A
WHEN C > LEAST(A, B, C) AND C < GREATEST (A, B, C) THEN C
ELSE B
END
WHERE NOT (A <= B AND B <= C);

它使用LEAST()GREATEST()来获取AC
的值,CASE检查哪个是B的中间值。

最新更新