Oracle
為記錄的後續值添加列
我有一個結構如下的表:
CREATE TABLE t ( HHID varchar2(1), INDIV_ID int, PRIM varchar2(1) ); insert into t values ('A', 10, 'Y'); insert into t values ('A', 11, 'N'); insert into t values ('A', 12, 'N'); insert into t values ('A', 13, 'N'); insert into t values ('B', 14, 'N'); insert into t values ('B', 15, 'Y'); insert into t values ('C', 16, 'Y'); insert into t values ('C', 17, 'N');
我需要將其轉換為以下內容:
HHID PRIMARY SECOND THIRD FOURTH FIFTH .... A 10 11 12 13 B 15 14 C 16 17
大問題是可能添加的列的數量是未知的,我只需要主要的 INDIV_ID 顯示為主要的,並且在後續列中擷取任何附加資訊。
我現在看到的每個答案都只建議將行 id 簡單地轉換為列 ID 的情況的答案,但是,我還沒有看到一個可以將相同 HHID 的後續記錄作為附加列放置的樞軸.
要首先獲取主值,然後按 indiv_id 獲取值,請為每行分配一個從 1 開始的每個 hhid 的數字:
row_number() over ( partition by hhid order by prim desc, indiv_id ) rn
一旦你得到了它,你就可以通過值 1、2、3、…、N 進行旋轉。
with rws as ( select hhid, indiv_id, row_number() over ( partition by hhid order by prim desc, indiv_id ) rn from t ) select * from rws pivot ( min(indiv_id) for rn in ( 1, 2, 3, 4 ) ); HHID 1 2 3 4 A 10 11 12 13 B 15 14 <null> <null> C 16 17 <null> <null>
如果您知道(或可以做出合理的猜測……)關於最大行數/隱藏,您就完成了。如果您希望輸出中的列發生變化,則沒有簡單的解決方案。
您可以 XML 透視:
with rws as ( select hhid, indiv_id, row_number() over ( partition by hhid order by prim desc, indiv_id ) rn from t ) select * from rws pivot xml ( min(indiv_id) for rn in ( any ) ); H - RN_XML ------------------------------------------------------------------------------------------------------------------------ A <PivotSet><item><column name = "RN">1</column><column name = "MIN(INDIV_ID)">10</column></item><item><column name = "RN" >2</column><column name = "MIN(INDIV_ID)">11</column></item><item><column name = "RN">3</column><column name = "MIN(INDI V_ID)">12</column></item><item><column name = "RN">4</column><column name = "MIN(INDIV_ID)">13</column></item></PivotSet > B <PivotSet><item><column name = "RN">1</column><column name = "MIN(INDIV_ID)">15</column></item><item><column name = "RN" >2</column><column name = "MIN(INDIV_ID)">14</column></item></PivotSet> C <PivotSet><item><column name = "RN">1</column><column name = "MIN(INDIV_ID)">16</column></item><item><column name = "RN" >2</column><column name = "MIN(INDIV_ID)">17</column></item></PivotSet>
但這有點作弊,因為您仍然有一個專欄。你需要解析 XML ……
或者您可以使用動態 SQL:
var cur refcursor; declare in_list varchar2(10); begin with rws as ( select distinct row_number() over ( partition by hhid order by prim desc, indiv_id ) rn from t ) select listagg(rn, ',') within group (order by rn) into in_list from rws; open :cur for 'with rws as ( select hhid, indiv_id, row_number() over ( partition by hhid order by prim desc, indiv_id ) rn from t ) select * from rws pivot ( min(indiv_id) for rn in ( ' || in_list || ' ) )'; end; / print :cur; H 1 2 3 4 - ---------- ---------- ---------- ---------- A 10 11 12 13 B 15 14 <null> <null> C 16 17 <null> <null>