我正在尝试解决以下问题:
编写一个SQL查询以交换表的一列中的两个相邻行。
输入表
Name Id
A 1
B 2
C 3
D 4
E 5
输出表
Name Id
A 2
B 1
C 4
D 3
E 5
描述:-1与A关联,2与B关联,交换它们,因此现在1与B关联,2与A关联,对于C和D同样如此,由于E没有任何对,因此将其保留为是的。
注意:-这可以使用CASE语句解决,但我正在尝试一种通用解决方案,说目前只有5行,可能是10,20等。
例如:
SELECT
*,CASE WHEN Name = A then 2 ELSEIF Name = B then 1 etc...
FROM YourTable
答案 0 :(得分:1)
您可以使用窗口函数来解决此问题。
在MySQL(> = 8.0)上:
SELECT ID, IFNULL(CASE WHEN t.rn % 2 = 0 THEN LAG(Name) OVER (ORDER BY ID) ELSE LEAD(Name) OVER (ORDER BY ID) END, Name) AS Name
FROM (
SELECT ID, Name, ROW_NUMBER() OVER (ORDER BY ID) AS rn
FROM table_name
) t
在SQL Server上:
SELECT ID, ISNULL(CASE WHEN t.rn % 2 = 0 THEN LAG(Name) OVER (ORDER BY ID) ELSE LEAD(Name) OVER (ORDER BY ID) END, Name) AS Name
FROM (
SELECT ID, Name, ROW_NUMBER() OVER (ORDER BY ID) AS rn
FROM table_name
) t
答案 1 :(得分:1)
如果您有sql-server
,可以尝试一下。
DECLARE @YourTable TABLE (Name VARCHAR(10), Id INT)
INSERT INTO @YourTable VALUES
('A', 1),
('B', 2),
('C', 3),
('D', 4),
('E', 5)
;WITH CTE AS (
SELECT *, ROW_NUMBER()OVER(ORDER BY Name) AS RN FROM @YourTable
)
SELECT T1.Name, ISNULL(T2.Id, T1.Id) Id FROM CTE T1
LEFT JOIN CTE T2 ON T1.RN + CASE WHEN T1.RN%2 = 0 THEN - 1 ELSE 1 END = T2.RN
结果:
Name Id
---------- -----------
A 2
B 1
C 4
D 3
E 5
答案 2 :(得分:0)
您没有指定DBMS,但是以下是标准的ANSI SQL。
您可以使用values()
子句来提供ID的映射,然后加入该映射:
with id_map (source_id, target_id) as (
values
(1, 2),
(2, 1)
)
select t.name, coalesce(m.target_id, t.id) as mapped_id
from the_table t
left join id_map m on m.source_id = t.id
order by name;
或者,如果您只想为一个方向指定一次映射,则可以使用以下方法:
with id_map (source_id, target_id) as (
values
(1, 2)
)
select t.name,
case id
when m.source_id then m.target_id
when m.target_id then m.source_id
else id
end as mapped_id
from the_table t
left join id_map m on t.id in (m.source_id, m.target_id)
order by name;