Почему этот запрос левого внешнего соединения не работает должным образом? - PullRequest
1 голос
/ 04 июля 2011

У меня есть таблица, которая выглядит так:

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

Я явно что-то делаю не так.Есть идеи?Я использую PostgreSQL 9.0.4 в Mac OS X 10.6.7.

Редактировать: Подумав об этом еще немного, мне нужно оставить внешнее соединение не только с месяцами, но и спротив счетов.Этот запрос выполняет именно то, что я хочу:

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 строк для данных за четыре года.

Ответы [ 2 ]

3 голосов
/ 04 июля 2011

Две вещи:

  • обратный порядок двух таблиц в LEFT JOIN и
  • переместить условие из условия WHERE в предложение 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 голосов
/ 04 июля 2011

Ваш 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.

...