PostgreSQL: синтаксис левого внешнего соединения - PullRequest
3 голосов
/ 02 января 2011

Я использую 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'.

Что я делаю не так, пожалуйста?

Ответы [ 3 ]

5 голосов
/ 02 января 2011
select u.id,
       u.first_name,
       u.city,
       u.avatar,
       coalesce(m.money,0),
       u.login > u.logout as online
  from pref_users u left outer join pref_money m on u.id=m.id
       and m.yw=to_char(current_timestamp, 'YYYY-IW') 
 where u.id='DE2'
 order by m.money desc;
1 голос
/ 02 января 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;
1 голос
/ 02 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...