PostgreSQL: синтаксис левого внешнего соединения

Я использую PostgreSQL 8.4.6 с CentOS 5.5 и имею таблицу пользователей:

# select * from pref_users where id='DE2';
 id  | first_name | last_name | female |      avatar      |        city         | lat | lng |           login            | last_ip | medals |           logout
-----+------------+-----------+--------+------------------+---------------------+-----+-----+----------------------------+---------+--------+----------------------------
 DE2 | Alex       |           | f      | 2_1280837766.jpg | г. Бохум в Германии |     |     | 2011-01-02 19:26:37.790909 |         |        | 2011-01-02 19:29:30.197062
(1 row)

и еще одна таблица, в которой перечислены их «виртуальные деньги», выигранные в игре каждую неделю:

# select * from pref_money where id='DE2';
 id  | money |   yw
-----+-------+---------
 DE2 |    66 | 2010-48
(1 row)

Затем я пытаюсь отобразить обе эти информации для пользователя, но меня интересуют только деньги пользователя за текущую неделю:

# select u.id,
    u.first_name,
    u.city,
    u.avatar,
    m.money,
    u.login > u.logout as online
from pref_users u, pref_money m where
    m.yw=to_char(current_timestamp, 'YYYY-IW') and
    u.id=m.id and
    u.id='DE2'
order by m.money desc;
 id | first_name | city | avatar | money | online
----+------------+------+--------+-------+--------
(0 rows)

В этом случае у меня нет строк, потому что пользователь 'DE2' еще не заработал "виртуальные деньги" на этой неделе.

Я хочу изменить свой запрос, чтобы он всегда возвращал данные для существующих пользователей, а если они не играли на этой неделе, то запрос должен возвращать 0.

Итак, я думаю, мне нужно внешнее левое соединение и я пытаюсь:

 select u.id,
    u.first_name,
    u.city,
    u.avatar,
    m.money,
    u.login > u.logout as online
from pref_users u left outer join pref_money m on (
    m.yw=to_char(current_timestamp, 'YYYY-IW') and
    u.id=m.id and
    u.id='DE2')
order by m.money desc;

но они возвращают мне много строк с разными пользователями, а не только одну с id='DE2'.

Что я делаю неправильно, пожалуйста?


person Alexander Farber    schedule 02.01.2011    source источник


Ответы (3)


Вы хотите поместить условие фильтра u.id='DE2' в предложение WHERE, оставив все остальное в предложении ON. Для каждого пользователя, у которого ON не совпадает, он по-прежнему будет выводить строку с данными из u и нулями для m.

person araqnid    schedule 02.01.2011

Попробуйте переместить

u.id='DE2'

в предложение WHERE, например:

select u.id,
    u.first_name,
    u.city,
    u.avatar,
    m.money,
    u.login > u.logout as online
from pref_users u left outer join pref_money m on u.id=m.id
where m.yw=to_char(current_timestamp, 'YYYY-IW') and
    u.id='DE2'
order by m.money desc;
person Ilya Kogan    schedule 02.01.2011

person    schedule
comment
РЕДАКТИРОВАТЬ: добавил m.yw обратно в предложение - person Daniel; 02.01.2011