Разделите 2 столбца на 4 на основе нечетного и четного - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу разделить 2 столбца на 4 на четных и нечетных. У меня есть таблица

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

Результаты, которые я получаю по запросу: -

enter image description here

Но я хочу получить результат в следующем формате: -

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

Ответы [ 3 ]

2 голосов
/ 17 февраля 2020

Другие ответы кажутся такими сложными. На самом деле это просто агрегация и арифметика c:

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);

Здесь - это дБ <> скрипка.

Примечание: вам даже не нужно rnk если вы знаете, что id является последовательным без пробелов.

1 голос
/ 17 февраля 2020

Вы также можете попробовать это:

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
1 голос
/ 17 февраля 2020

Вам нужно сгенерировать нечетные и четные заголовки и описания отдельно, а затем вы можете 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   

Демо на dbfiddle

...