2016-10-20 43 views
0

我有2個表。表用戶存儲下面的用戶信息。動態創建行到列(Oracle)

**user_id  user_name** 
1   naveen 
2   richard 
3   reddy 

另一張表User_activity。存儲用戶計劃的詳細信息。

**user_id  Activity date** 
1   holiday 1-aug-2016 
2   working 1-aug-2016 
3   training 1-aug-2016 
1   working 2-aug-2016 
2   working 2-aug-2016 
3   working 2-aug-2016 

現在我需要以下面的格式創建報告。請幫我寫一個相同的查詢。

**Date   naveen  Richard  reddy** 
1-aug-2016 holiday  working  training 
2-aug-2016 working  working  working 
+0

你試過什麼了?如果你有3個以上的用戶呢?你期望構建一個可變數量列的查詢嗎? – Aleksej

+0

只是通過樞軸功能工作。但是,正如你告訴我,如果沒有用戶超過3個,我就無法創建。尋找最佳解決方案。 –

+1

你不能建立一個簡單的SQL返回一個列數可變的結果。你可以構建一個動態SQL然後運行它,這會給出可變數量的列,但是如何處理這個結果呢?其他方式,您可以使用包含值的串聯的單個列與一些分隔符構建結果 – Aleksej

回答

0

沒辦法做到這一點。 (PIVOT_XML除外)。

長話短說: 當您執行查詢時,Oracle會向您發送列及其數據類型的說明。甚至在它實際觸及任何數據之前。

Oracle使用生產者 - 消費者原則,因此數據在評估時發送到客戶端 - 結果集不在服務器端進行緩衝。

所以你的要求違背了這個原則。如果列數取決於數據內容,Oracle將不得不隨時更改結果集參數 - 這是不可能的。

PIVOT_XML是一個例外,因爲它只生成一個CLOB列。

0

你可以嘗試一些稍微不同的東西,用包含數據連接的單個列構建輸出。 假設每個用戶都有每一天完全是一個活動,你可以嘗試這樣的事情:

with users(user_id, user_name) as 
(
    select 1, 'naveen' from dual union all 
    select 2, 'richard' from dual union all 
    select 3, 'reddy' from dual 
), 
user_activity(user_id, Activity, activity_date) as 
(
    select 1, 'holiday' , date '2016-08-01' from dual union all 
    select 2, 'working' , date '2016-08-01' from dual union all 
    select 3, 'training' , date '2016-08-01' from dual union all 
    select 1, 'working' , date '2016-08-02' from dual union all 
    select 2, 'working' , date '2016-08-02' from dual union all 
    select 3, 'working' , date '2016-08-02' from dual 
) 
select rpad('Date', 16, ' ') || ',' || listagg(rpad(user_name, 16, ' '), ',') within group (order by user_id) 
from users 
union all 
select rpad(to_char(activity_date, 'yyyy-mm-dd'),16, ' ') || ',' || listagg(rpad(activity, 16, ' '), ',') within group (order by user_id) 
from users 
     inner join user_activity using(user_id) 
group by activity_date 

結果:

RPAD('DATE',16,'')||','||LISTAGG(RPAD(USER_NAME,16,''),',')WITHINGROUP(ORDERBYUS 
-------------------------------------------------------------------------------- 
Date   ,naveen   ,richard   ,reddy 
2016-08-01  ,holiday   ,working   ,training 
2016-08-02  ,working   ,working   ,working 

如果我添加第四個男人:

RPAD('DATE',16,'')||','||LISTAGG(RPAD(USER_NAME,16,''),',')WITHINGROUP(ORDERBYUSER_ID) 
---------------------------------------------------------------------------------------------------- 
Date   ,naveen   ,richard   ,reddy   ,Fourth Man 
2016-08-01  ,holiday   ,working   ,training  ,training 
2016-08-02  ,working   ,working   ,working   ,working