2011-07-04 57 views
1

我有一個表,看起來像這樣:爲什麼這個左外連接查詢不能正常工作?

peter=> \d aggregated_accounts_by_month 
Table "public.aggregated_accounts_by_month" 
    Column | Type | Modifiers 
-----------+---------+----------- 
xtn_month | date | 
account | text | 
commodity | text | 
amount | numeric | 
Indexes: 
    "idx_aggregated_accounts_by_month_account" btree (account) 
    "idx_aggregated_accounts_by_month_month" btree (xtn_month) 

而且看起來像這樣的另一個表:

peter=> \d months 
    Table "pg_temp_2.months" 
    Column | Type | Modifiers 
-----------+------+----------- 
xtn_month | date | 

months包含此:

xtn_month 
------------ 
2011-01-01 
2011-02-01 
2011-03-01 
2011-04-01 
2011-05-01 
2011-06-01 
2011-07-01 

aggregated_accounts_by_month包含此相關的數據:

xtn_month | account | amount 
------------+---------------+-------- 
2011-01-01 | Expenses:Fuel | 111.31 
2011-02-01 | Expenses:Fuel | 89.29 
2011-03-01 | Expenses:Fuel | 97.41 
2011-04-01 | Expenses:Fuel | 101.70 
2011-05-01 | Expenses:Fuel | 52.9 
2011-07-01 | Expenses:Fuel | 49.55 

我試圖運行的查詢是:

select 
    months.xtn_month, 
    account, 
    amount 
from 
    aggregated_accounts_by_month a 
    left outer join months on months.xtn_month = a.xtn_month 
where 
    account = 'Expenses:Fuel' 
order by 
    xtn_month; 

我想要的這個查詢做的就是給我的結果:

xtn_month | account | amount 
------------+---------------+-------- 
2011-01-01 | Expenses:Fuel | 111.31 
2011-02-01 | Expenses:Fuel | 89.29 
2011-03-01 | Expenses:Fuel | 97.41 
2011-04-01 | Expenses:Fuel | 101.70 
2011-05-01 | Expenses:Fuel | 52.9 
2011-06-01 | Expenses:Fuel | 
2011-07-01 | Expenses:Fuel | 49.55 

但它實際上給我這個:

xtn_month | account | amount 
------------+---------------+-------- 
2011-01-01 | Expenses:Fuel | 111.31 
2011-02-01 | Expenses:Fuel | 89.29 
2011-03-01 | Expenses:Fuel | 97.41 
2011-04-01 | Expenses:Fuel | 101.70 
2011-05-01 | Expenses:Fuel | 52.9 
2011-07-01 | Expenses:Fuel | 49.55 

我明顯在做錯事。有任何想法嗎?我在Mac OS X 10.6.7上運行PostgreSQL 9.0.4。

編輯:考慮到這一點之後,我需要對抗外部連接不僅僅是個月,還要對賬戶。該查詢不正是我想要的東西:

select 
    xtn_month, 
    account, 
    coalesce(amount, 0) 
from 
    (
     select 
      xtn_month, 
      account 
     from 
     (
      select 
       distinct xtn_month 
      from 
       aggregated_accounts_by_month 
     ) x 
     cross join 
     (
      select 
       distinct account 
      from 
       aggregated_accounts_by_month 
     ) y 
    ) z 
    left outer join aggregated_accounts_by_month 
     using (xtn_month, account) 
where 
    account = 'Expenses:Fuel' 
order by 
    xtn_month; 

ypercube的回答是幾乎正確的,但它並沒有在account欄中填入。這個查詢當然相當昂貴,那裏有那個交叉產品。沒關係,但是,因爲aggregated_accounts_by_month有超過四年的數據少於2000行。

回答

3

兩件事情:

  • WHERE條件反轉兩個表的順序在LEFT JOIN
  • 移動到ON子句。

select 
    months.xtn_month, 
    a.account, 
    a.amount 
from 
    months 
    left outer join aggregated_accounts_by_month a 
     on months.xtn_month = a.xtn_month 
     and a.account = 'Expenses:Fuel' 
order by 
    xtn_month; 
+0

這完全有效,並且實際解釋了爲什麼我的查詢不起作用。 'account'列結尾爲null,因爲它不在月份表中,因此'where'子句過濾出該行。謝謝! –

0

您的aggregated_accounts_by_month不包含2011-06-01。你實際上可能會尋找一個完整的加盟:

select 
    months.xtn_month, 
    account, 
    amount 
from 
    aggregated_accounts_by_month a 
    full join months on months.xtn_month = a.xtn_month 
where 
    account = 'Expenses:Fuel' 
order by 
    xtn_month; 

另外,左連接其他兩個答案建議,即months,然後aggregated_accounts_by_month

相關問題