2012-11-15 65 views
0

我不確定如何以Google能理解的方式提出此問題。我想離開了連接兩個表,並有填補空白領域這裏就是我的工作。Oracle SQL左值加入空值複製

tbl1 
| user | date | usage | 
| us1 | 01/12 | 503 | 
| us1 | 02/12 | 245 | 
| us1 | 03/12 | 465 | 
| us2 | 02/12 | 327 | 
| us2 | 03/12 | 204 | 
| us3 | 02/12 | 156 | 

tbl2 
| dates | avg_use | 
| 01/12 | 345 | 
| 02/12 | 426 | 
| 03/12 | 502 | 

Desired output 
| user | date | usage | pct_of_avg | 
| us1 | 01/12 | 503 |  1.45  | 
| us1 | 02/12 | 245 |  .58  | 
| us1 | 03/12 | 465 |  .93  | 
| us2 | 01/12 | (null) |  0  | 
| us2 | 02/12 | 327 |  .95  | 
| us2 | 03/12 | 204 |  .41  | 
| us3 | 01/12 | (null) |  0  | 
| us3 | 02/12 | 156 |  .37  | 
| us3 | 03/12 | (null) |  0  | 

我明白JOIN的很好,所以我知道,一個典型的聯接將無法這樣做是因爲tbl1.user中的數據不存在。有沒有辦法在SQL中完成此操作?給了我想要做一個名字,因爲它會幫助很多獎勵積分只知道如何給Google這個:)

回答

3

這應做到:

SELECT U.user, T2.dates date, T1.usage, T1.usage/T2.avg_use pct_of_avg 
FROM (SELECT DISTINCT user FROM tbl1) U 
CROSS JOIN tbl2 T2 
LEFT JOIN tbl1 T1 
    ON T2.date = T1.date AND U.user = T1.user 
+0

這不會提供願望輸出,因爲它不會有用戶沒有數據的日期行。這個問題的目的是爲每一個日期和每個用戶獲取一行。 – monitorjbl

+0

@monitorjbl真的嗎?,你嘗試過嗎?,我敢肯定,我的答案確實考慮到每個用戶都有結果的每個日期,這就是'CROSS JOIN'正在做什麼 – Lamak

+1

您編輯了您的回覆。你的第一個查詢沒有,但這是一個。謝謝,這正是我需要的! – monitorjbl

2

如果您了Oracle 10g或更高,你可以使用partition by擴展outer join來填補數據中的空白。您將需要更少的代碼。它會更簡單,更快。

SQL> select t.user1 
    2  , to_char(t1.dates, 'mm/yy') as date1 
    3  , t.usage1 
    4  , round((nvl(t.usage1, 0)/t1.avg_use), 2) as pct_of_avg 
    5 from tbl1 t 
    6 partition by(t.user1) 
    7 right join tbl2 t1 
    8  on (t.date1 = t1.dates) 
    9 ; 

USER1 DATE1  USAGE1 PCT_OF_AVG 
----- ----- ---------- ---------- 
us1 01/12  503  1.46 
us1 02/12  245  0.58 
us1 03/12  465  0.93 
us2 01/12      0 
us2 02/12  327  0.77 
us2 03/12  204  0.41 
us3 01/12      0 
us3 02/12  156  0.37 
us3 03/12      0 

9 rows selected