2016-02-25 4 views
0

Здравствуйте, у меня есть очень большой набор данных, где я хочу динамически создавать столбцы и размещать значения в строках.dynamic pivot plsql

Ниже набор данных

Colorid color 
1  Red 
1  Blue 
1  Yellow 
2  Grey 
2  Red 

Это то, что я хочу вернуться. Я не думаю, что мне нужна динамический стержень, но не уверен, о да, и никаком это

Colorid red blue yellow grey 
1  Yes yes yes 
2  Yes no No  Yes 

Благодаря

+0

Есть те 'color's' фиксированной –

+0

Редко когда-либо изменить. Итак, скажем, для этого они не изменятся. FYI в моей реальной программе там будет как 100 некоторых цветов –

+0

Возможный дубликат [Динамический поворот строк в столбцы в Oracle] (http://stackoverflow.com/questions/7730111/pivoting-rows-into-columns-dynamically-in- oracle) –

ответ

0

Если вам нужно использовать результат в функции или процедуре pl sql, вы можете сделать следующее.

DECLARE 
-- Local variables here 
sql_   VARCHAR2(32000); 
l_colCnt  NUMBER; 
l_descTbl  dbms_sql.desc_tab; 
fdbk   NUMBER; 
cur   NUMBER; 
pVarcharValue VARCHAR2(200); 
BEGIN 
-- Test statements here 
sql_ := 'select to_char(Colorid) Colorid '; 
FOR c IN (SELECT DISTINCT color FROM COLOR_TABLE ORDER BY color) LOOP 
     sql_ := sql_ || ', nvl((select ''yes'' from COLOR_TABLE where Colorid=a.Colorid and color=''' || c.color || '''),''no'') ' || c.color || ' '; 
END LOOP; 
sql_ := sql_ || ' from (select distinct Colorid from COLOR_TABLE) a'; 

cur := DBMS_SQL.open_cursor; 
DBMS_SQL.PARSE(cur, sql_, DBMS_SQL.V7); 
dbms_sql.describe_columns(c => cur, col_cnt => l_colCnt, desc_t => l_descTbl); 

FOR i IN 1 .. l_colCnt LOOP 
     dbms_output.put(l_descTbl(i).col_name||' '); -- Here name of column 
     dbms_sql.define_column(cur, i, pVarcharValue, 200); 
END LOOP; 
dbms_output.put_line(NULL); 
fdbk := DBMS_SQL.execute(cur); 
LOOP 
     fdbk := DBMS_SQL.fetch_rows(cur); 

     EXIT WHEN fdbk = 0; 
     FOR i IN 1 .. l_colCnt LOOP 
      dbms_sql.column_value(cur, i, pVarcharValue); 
      dbms_output.put(pVarcharValue || ' '); -- Here stored value of current row and column. One cell. 
     END LOOP; 
     dbms_output.put_line(NULL); 
END LOOP; 
END; 

Если вам нужно sys_refcursor лет можно сделать:

DECLARE 
-- Local variables here 
sql_   VARCHAR2(32000); 
curs   SYS_REFCURSOR; 
BEGIN 
-- Test statements here 
sql_ := 'select to_char(Colorid) Colorid '; 
FOR c IN (SELECT DISTINCT color FROM COLOR_TABLE ORDER BY color) LOOP 
     sql_ := sql_ || ', nvl((select ''yes'' from COLOR_TABLE where Colorid=a.Colorid and color=''' || c.color || '''),''no'') ' || c.color || ' '; 
END LOOP; 
sql_ := sql_ || ' from (select distinct Colorid from COLOR_TABLE) a'; 
OPEN curs FOR sql_; -- here init sys_refcursor 
END; 
-1

Привет, мы можем достичь этого с помощью Pivot и IIF состояния

Нормального запроса

DECLARE @Table1 TABLE 
    (Colorid int, color varchar(6)) 
; 

INSERT INTO @Table1 
    (Colorid, color) 
VALUES 
    (1, 'Red'), 
    (1, 'Blue'), 
    (1, 'Yellow'), 
    (2, 'Grey'), 
    (2, 'Red') 
; 

Select Colorid,IIF([Red] IS NOT NULL,'YES','NO')[Red],IIF([Blue] IS NOT NULL,'YES','NO')[Blue],IIF([Yellow] IS NOT NULL,'YES','NO')[Yellow],IIF([Grey] IS NOT NULL,'YES','NO')[Grey] from (
select Colorid, color,ROW_NUMBER()OVER(PARTITION BY color ORDER BY color)RN from @Table1 
GROUP BY Colorid, color)T 
PIVOT (MAX(RN) FOR color IN ([Blue],[Red],[Yellow],[Grey]))P 

Динамический запрос

if object_id('tempdb..#t') is not null 
    drop table #t 


CREATE TABLE #t 
    (Colorid int, color varchar(6)) 
; 

INSERT INTO #t 
    (Colorid, color) 
VALUES 
    (1, 'Red'), 
    (1, 'Blue'), 
    (1, 'Yellow'), 
    (2, 'Grey'), 
    (2, 'Red') 
; 


DECLARE @statement NVARCHAR(max) 
,@columns NVARCHAR(max) 

SELECT @columns = ISNULL(@columns + ', ', '') + N'[' + tbl.color + ']' 
FROM (
    SELECT DISTINCT color 
    FROM #t 
    ) AS tbl 

SELECT @statement = ' Select Colorid,IIF([Red] IS NOT NULL,''YES'',''NO'')[Red], 
IIF([Blue] IS NOT NULL,''YES'',''NO'')[Blue], 
IIF([Yellow] IS NOT NULL,''YES'',''NO'')[Yellow], 
IIF([Grey] IS NOT NULL,''YES'',''NO'')[Grey] from (
select Colorid, color,ROW_NUMBER()OVER(PARTITION BY color ORDER BY color)RN from #t 
GROUP BY Colorid, color)T 
PIVOT (MAX(RN) FOR color IN (' + @columns + ')) as pvt' 

EXEC sp_executesql @statement = @statement 
+0

@codemonger, пожалуйста, проверьте – mohan111

+0

Вопрос помечен 'PLSQL' –

+0

бог, это действительно получается на мне .. @ MotoGP не видел – mohan111