>我试图只在一行内交换两列。
例如,我们有这样一个表:
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 > C
或B > 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()
来获取A
和C
的值,CASE
检查哪个是B
的中间值。