根据奇数和偶数将2列分成4列
Divide 2 columns into 4 based on odd and even
我想把2列按照奇数和偶数分成4列。我有一个 table
INSERT INTO @tab
VALUES ('test', 'desc'), ('test1', 'desc1'), ('test2', 'desc2'),
('test3', 'desc3'), ('test4', 'desc4')
我尝试了以下查询:-
SELECT
CASE
WHEN A.RNK % 2 = 1
THEN Heading
END AS Headingodds,
CASE
WHEN A.RNK % 2 = 0
THEN Heading
END AS Headingeven,
CASE
WHEN A.RNK % 2 = 1
THEN A.[Description]
END AS Descriptionodds,
CASE
WHEN A.RNK % 2 = 0
THEN A.[Description]
END AS Descriptioneven
FROM
(SELECT
Id, Heading, [Description],
ROW_NUMBER() OVER (ORDER BY Id) AS RNK
FROM
@tab) A
我从查询中得到的结果是:-
但我想要以下格式的结果:-
DECLARE @tab1 TABLE(Headingodd VARCHAR(100), Headingeven VARCHAR(100), Descriptionodd VARCHAR(100), Descriptioneven VARCHAR(100))
INSERT INTO @tab1
VALUES ('test', 'test1', 'desc', 'desc1'),
('test2', 'test3', 'desc2', 'desc3'),
('test4', null, 'desc4', null)
SELECT * FROM @tab1
您需要分别生成奇数和偶数标题和描述,然后您可以 JOIN
在匹配的行号上将它们一起
WITH A AS (
SELECT Id, Heading, [Description],
ROW_NUMBER() OVER (ORDER BY Id) AS RNK
FROM tab
),
ODD AS (
SELECT Heading, [Description],
(RNK - 1) / 2 AS RN
FROM A
WHERE RNK % 2 = 1
),
EVEN AS (
SELECT Heading, [Description],
(RNK - 1) / 2 AS RN
FROM A
WHERE RNK % 2 = 0
)
SELECT o.Heading AS Headingodds,
e.Heading AS Headingeven,
o.Description AS Descriptionodds,
e.Description AS Descriptioneven
FROM ODD o
LEFT JOIN EVEN e ON e.RN = o.RN
ORDER BY o.RN
输出:
Headingodds Headingeven Descriptionodds Descriptioneven
test test1 desc desc1
test2 test3 desc2 desc3
test4 desc4
你也可以试试这个:
create table #tab(id int,test varchar(40),des varchar(40))
INSERT INTO #tab
VALUES (1,'test', 'desc'), (2,'test1', 'desc1'), (3,'test2', 'desc2'),
(4,'test3', 'desc3'), (5,'test4', 'desc4')
select * from #tab
with cte as
(select ROW_NUMBER()OVER(ORDER BY a.TestODD) row_num,*
from (select(case when id in (1,3,5) then '0' else test end) TestODD from #tab) a
where a.TestODD!='0'),
cte2 as (
select ROW_NUMBER() OVER(ORDER BY b.TestEven)row_num,*
from (select(case when id in(2,4)then '0' else test end)TestEven from #tab)b
where b.TestEven!='0'
),
cte3 as (
select ROW_NUMBER()OVER(ORDER BY c.desODD) row_num,*
from (select (case when id in (1,3,5)then '0' else des end) desODD from #tab)c
where c.desODD!='0'
),
cte4 as (
select ROW_NUMBER()OVER(ORDER BY d.destEven)row_num,*
from (select(case when id in (2,4)then '0' else des end)destEven from #tab) d
where d.destEven!='0'
)
select TestEven,TestODD,destEven,desODD from cte2
left join cte on cte.row_num=cte2.row_num
left join cte3 on cte2.row_num=cte3.row_num
left join cte4 on cte2.row_num=cte4.row_num
其他答案看起来太复杂了。这实际上只是聚合和算术:
select min(case when rnk % 2 = 1 then heading end) as heading_odd,
min(case when rnk % 2 = 0 then heading end) as heading_even,
min(case when rnk % 2 = 1 then description end) as description_odd,
min(case when rnk % 2 = 0 then description end) as description_even
from (select t.*, row_number() over (order by id) as rnk
from tab t
) t
group by (rnk - 1) / 2
order by min(rnk);
Here 是一个 db<>fiddle.
注意:如果您知道 id
是连续的且没有间隙,您甚至不需要 rnk
。
我想把2列按照奇数和偶数分成4列。我有一个 table
INSERT INTO @tab
VALUES ('test', 'desc'), ('test1', 'desc1'), ('test2', 'desc2'),
('test3', 'desc3'), ('test4', 'desc4')
我尝试了以下查询:-
SELECT
CASE
WHEN A.RNK % 2 = 1
THEN Heading
END AS Headingodds,
CASE
WHEN A.RNK % 2 = 0
THEN Heading
END AS Headingeven,
CASE
WHEN A.RNK % 2 = 1
THEN A.[Description]
END AS Descriptionodds,
CASE
WHEN A.RNK % 2 = 0
THEN A.[Description]
END AS Descriptioneven
FROM
(SELECT
Id, Heading, [Description],
ROW_NUMBER() OVER (ORDER BY Id) AS RNK
FROM
@tab) A
我从查询中得到的结果是:-
但我想要以下格式的结果:-
DECLARE @tab1 TABLE(Headingodd VARCHAR(100), Headingeven VARCHAR(100), Descriptionodd VARCHAR(100), Descriptioneven VARCHAR(100))
INSERT INTO @tab1
VALUES ('test', 'test1', 'desc', 'desc1'),
('test2', 'test3', 'desc2', 'desc3'),
('test4', null, 'desc4', null)
SELECT * FROM @tab1
您需要分别生成奇数和偶数标题和描述,然后您可以 JOIN
在匹配的行号上将它们一起
WITH A AS (
SELECT Id, Heading, [Description],
ROW_NUMBER() OVER (ORDER BY Id) AS RNK
FROM tab
),
ODD AS (
SELECT Heading, [Description],
(RNK - 1) / 2 AS RN
FROM A
WHERE RNK % 2 = 1
),
EVEN AS (
SELECT Heading, [Description],
(RNK - 1) / 2 AS RN
FROM A
WHERE RNK % 2 = 0
)
SELECT o.Heading AS Headingodds,
e.Heading AS Headingeven,
o.Description AS Descriptionodds,
e.Description AS Descriptioneven
FROM ODD o
LEFT JOIN EVEN e ON e.RN = o.RN
ORDER BY o.RN
输出:
Headingodds Headingeven Descriptionodds Descriptioneven
test test1 desc desc1
test2 test3 desc2 desc3
test4 desc4
你也可以试试这个:
create table #tab(id int,test varchar(40),des varchar(40))
INSERT INTO #tab
VALUES (1,'test', 'desc'), (2,'test1', 'desc1'), (3,'test2', 'desc2'),
(4,'test3', 'desc3'), (5,'test4', 'desc4')
select * from #tab
with cte as
(select ROW_NUMBER()OVER(ORDER BY a.TestODD) row_num,*
from (select(case when id in (1,3,5) then '0' else test end) TestODD from #tab) a
where a.TestODD!='0'),
cte2 as (
select ROW_NUMBER() OVER(ORDER BY b.TestEven)row_num,*
from (select(case when id in(2,4)then '0' else test end)TestEven from #tab)b
where b.TestEven!='0'
),
cte3 as (
select ROW_NUMBER()OVER(ORDER BY c.desODD) row_num,*
from (select (case when id in (1,3,5)then '0' else des end) desODD from #tab)c
where c.desODD!='0'
),
cte4 as (
select ROW_NUMBER()OVER(ORDER BY d.destEven)row_num,*
from (select(case when id in (2,4)then '0' else des end)destEven from #tab) d
where d.destEven!='0'
)
select TestEven,TestODD,destEven,desODD from cte2
left join cte on cte.row_num=cte2.row_num
left join cte3 on cte2.row_num=cte3.row_num
left join cte4 on cte2.row_num=cte4.row_num
其他答案看起来太复杂了。这实际上只是聚合和算术:
select min(case when rnk % 2 = 1 then heading end) as heading_odd,
min(case when rnk % 2 = 0 then heading end) as heading_even,
min(case when rnk % 2 = 1 then description end) as description_odd,
min(case when rnk % 2 = 0 then description end) as description_even
from (select t.*, row_number() over (order by id) as rnk
from tab t
) t
group by (rnk - 1) / 2
order by min(rnk);
Here 是一个 db<>fiddle.
注意:如果您知道 id
是连续的且没有间隙,您甚至不需要 rnk
。