2016-05-18 7 views
0

Я думал, что смогу сделать это легче, чем решение, с которым я столкнулся. Поэтому я спрашиваю, возможно ли, чтобы иметь более простое решение следующей задачи:Транспонирование одной колонки на две колонки

У меня есть данные на одном формате колонки следующим образом:

COLUMN 1 
    ========= 
    partnumber 
    version 
    partnumber 
    version 
    partnumber 
    version 
    etc 

Каждый элемент идентифицируется номера изделия и версии. Версия элемента сразу следует за партией элемента. Тем не менее, я хотел бы данные в следующем формате:

COLUMN 1 COLUMN 2 
========== ========= 
partnumber version 
partnumber version 
partnumber version 
etc  etc 

я придумал следующие два альтернативных запросов:

with data as (
select col,rownum+mod(rownum,2) item_index,row_number() over (partition by rownum+mod(rownum,2) order by rownum) colno from(
select -2141 col from dual 
union all 
select 5 col from dual 
union all 
select -2102 col from dual 
union all 
select 2 col from dual 
union all 
select -2021 col from dual 
union all 
select 4 col from dual)) 
select t1.col,t2.col from (select col,item_index from data where colno=1) t1 
join (select col,item_index from data where colno=2) t2 
on t1.item_index=t2.item_index; 


with data as (
select col,rownum rn from (
select -2141 col from dual 
union all 
select 5 col from dual 
union all 
select -2102 col from dual 
union all 
select 2 col from dual 
union all 
select -2021 col from dual 
union all 
select 4 col from dual)) 
select t1.col,t2.col from (select col,rn+mod(rn,2) item_index from data where mod(rn,2)=1) t1 
join (select col,rn+mod(rn,2) item_index from data where mod(rn,2)=0) t2 
on t1.item_index=t2.item_index; 

Есть ли лучшая альтернатива?

+0

Как вы определяете "непосредственно следует"? Вы полагаетесь на порядок, в котором строки физически хранятся в базе данных? Что вы будете делать, когда это изменится по какой-либо причине? – mathguy

+1

Значения @mathguy хранятся в VARRAY. – user2672165

ответ

2

Oracle Setup:

CREATE TABLE data(value) AS 
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'etc'  FROM dual UNION ALL 
    SELECT 'etc'  FROM dual; 

Запрос:

SELECT * 
FROM (
    SELECT value, 
     CEIL(ROWNUM/2) AS id, 
     MOD(ROWNUM, 2) AS isPartNo 
    FROM DATA 
) 
PIVOT(MAX(value) FOR isPartNo IN (1 AS PartNumber, 0 AS Version)) 
ORDER BY id; 

Выход:

 ID PARTNUMBER VERSION 
---------- ---------- ---------- 
     1 partnumber version  
     2 partnumber version  
     3 partnumber version  
     4 etc  etc   
+0

Очень приятное решение, только один доступ к таблице. – Husqvik

+0

Отличное решение! – user2672165

1

Это выглядит немного проще для меня:

WITH data(value) AS (
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'partnumber' FROM dual UNION ALL 
    SELECT 'version' FROM dual UNION ALL 
    SELECT 'etc'  FROM dual UNION ALL 
    SELECT 'etc'  FROM dual), 
seq_data(seq, value) AS (
    SELECT ROWNUM, value FROM data 
) 
SELECT 
    t1.value column1, t2.value column2 
FROM 
    seq_data t1 
    JOIN seq_data t2 ON t1.seq = t2.seq - 1 
WHERE 
    mod(t1.seq, 2) = 1 
Смежные вопросы