2013-05-04 1 views
0

В PostgreSQL 8.4.13 У меня есть две таблицы, представляющие карточные игры (каждая из которых состоит из 3 игроков) и результаты оценки этих игр. Игроки идентифицируются id колонок и игры на gid:Выполнять true на соединенных таблицах

# \d pref_games 
            Table "public.pref_games" 
Column |   Type    |      Modifiers 
--------+-----------------------------+---------------------------------------------------------- 
gid | integer      | not null default nextval('pref_games_gid_seq'::regclass) 
rounds | integer      | not null 
stamp | timestamp without time zone | default now() 
Indexes: 
    "pref_games_pkey" PRIMARY KEY, btree (gid) 
Referenced by: 
    TABLE "pref_scores" CONSTRAINT "pref_scores_gid_fkey" FOREIGN KEY (gid) REFERENCES pref_games(gid) ON DELETE CASCADE 

# \d pref_scores 
     Table "public.pref_scores" 
Column |   Type   | Modifiers 
---------+-----------------------+----------- 
id  | character varying(32) | not null 
gid  | integer    | not null 
money | integer    | not null 
last_ip | inet     | 
quit | boolean    | 
Indexes: 
    "pref_scores_pkey" PRIMARY KEY, btree (id, gid) 
    "pref_scores_gid_index" btree (gid) 
Foreign-key constraints: 
    "pref_scores_gid_fkey" FOREIGN KEY (gid) REFERENCES pref_games(gid) ON DELETE CASCADE 
    "pref_scores_id_fkey" FOREIGN KEY (id) REFERENCES pref_users(id) ON DELETE CASCADE 

Я пытаюсь выяснить, если игрок с id='OK261593357402' когда-либо играл с игроком id='MR3689735717800138910' - так что я могу позволить им класс каждого другие на моем веб-сайте.

Мне кажется, мне нужно позвонить perform true по телефону inner join - это правильно, пожалуйста?

Так что я пытаюсь:

# select * from pref_games g inner join pref_scores s on (s.gid=g.gid) where s.id='OK261593357402'; 
    gid | rounds |   stamp   |  id  | gid | money | last_ip  | quit 
---------+--------+----------------------------+----------------+---------+-------+----------------+------ 
2124241 |  20 | 2013-05-01 12:26:54.052086 | OK261593357402 | 2124241 | 28 | 93.232.91.105 | f 
2125575 |  17 | 2013-05-01 16:53:21.090822 | OK261593357402 | 2125575 | 32 | 93.232.91.105 | f 
2125881 |  20 | 2013-05-01 17:47:26.15633 | OK261593357402 | 2125881 | -31 | 93.232.91.105 | f 
2126242 |  0 | 2013-05-01 18:41:06.769132 | OK261593357402 | 2126242 |  0 | 93.232.91.105 | f 
2126244 |  0 | 2013-05-01 18:41:12.495192 | OK261593357402 | 2126244 |  0 | 93.232.91.105 | t 
2126259 |  0 | 2013-05-01 18:42:39.974518 | OK261593357402 | 2126259 |  0 | 93.232.91.105 | t 
2126613 |  33 | 2013-05-01 19:27:11.88462 | OK261593357402 | 2126613 | -132 | 93.232.91.105 | f 
2126813 |  0 | 2013-05-01 19:57:05.23061 | OK261593357402 | 2126813 |  0 | 93.232.91.105 | t 
2127299 |  20 | 2013-05-01 20:36:42.021133 | OK261593357402 | 2127299 | 136 | 93.232.91.105 | f 
2127821 |  0 | 2013-05-01 21:33:32.168757 | OK261593357402 | 2127821 |  0 | 93.232.91.105 | f 
2127830 |  0 | 2013-05-01 21:34:47.694645 | OK261593357402 | 2127830 |  0 | 93.232.91.105 | t 
2128012 |  21 | 2013-05-01 22:04:03.850061 | OK261593357402 | 2128012 | 55 | 93.232.91.105 | f 
2129551 |  13 | 2013-05-02 10:08:37.348426 | OK261593357402 | 2129551 | -32 | 79.250.39.175 | f 
2129818 |  13 | 2013-05-02 11:21:50.998484 | OK261593357402 | 2129818 | 71 | 79.250.39.175 | f 
2130467 |  11 | 2013-05-02 13:55:00.034698 | OK261593357402 | 2130467 | -79 | 79.250.39.175 | f 
2130470 |  0 | 2013-05-02 13:55:41.298932 | OK261593357402 | 2130470 |  0 | 79.250.39.175 | f 
2130476 |  0 | 2013-05-02 13:56:22.359713 | OK261593357402 | 2130476 |  0 | 79.250.39.175 | f 
..... 

Но я вижу только id='OK261593357402' выше, то есть я ожидал увидеть все его игры партнеров тоже, но они не будут доставлены.

Я также попытался:

# select * from pref_games g left outer join pref_scores s on (s.gid=g.gid) where s.id='OK261593357402'; 
    gid | rounds |   stamp   |  id  | gid | money | last_ip  | quit 
---------+--------+----------------------------+----------------+---------+-------+----------------+------ 
2124241 |  20 | 2013-05-01 12:26:54.052086 | OK261593357402 | 2124241 | 28 | 93.232.91.105 | f 
2125575 |  17 | 2013-05-01 16:53:21.090822 | OK261593357402 | 2125575 | 32 | 93.232.91.105 | f 
2125881 |  20 | 2013-05-01 17:47:26.15633 | OK261593357402 | 2125881 | -31 | 93.232.91.105 | f 
2126242 |  0 | 2013-05-01 18:41:06.769132 | OK261593357402 | 2126242 |  0 | 93.232.91.105 | f 
2126244 |  0 | 2013-05-01 18:41:12.495192 | OK261593357402 | 2126244 |  0 | 93.232.91.105 | t 
2126259 |  0 | 2013-05-01 18:42:39.974518 | OK261593357402 | 2126259 |  0 | 93.232.91.105 | t 
2126613 |  33 | 2013-05-01 19:27:11.88462 | OK261593357402 | 2126613 | -132 | 93.232.91.105 | f 
2126813 |  0 | 2013-05-01 19:57:05.23061 | OK261593357402 | 2126813 |  0 | 93.232.91.105 | t 
... 

К сожалению тот же результат ...

Должен ли я, возможно, просто сделать серию select с в сочетании с exists in вместо этого?

+0

Что такое 'perform true'? Какой-то Oracle-ism или функция проприетарного расширения PostgreSQL? –

+0

Я имел в виду: 'PERFORM TRUE FROM ....', а затем 'IF FOUND THEN .... ENDIF' –

+0

О, вы говорите о' PERFORM' PL/PgSQL, альтернативе, отличной от результатов, для SELECT ', затем тестирование для' FOUND'. Хорошо, это имеет смысл. Вы никогда ничего не говорили о PL/PgSQL или о том, что вы пишете сохраненную функцию. (Это одна из причин, почему показ вашего кода в вопросах - хорошая идея). –

ответ

1

Я пытаюсь выяснить, если игрок с id='OK261593357402' имеет когда-либо играл с игроком id='MR3689735717800138910'

Это обычно короче/быстрее/проще/более элегантный использовать IF EXISTS ... в plpgsql, чем PERFORM с задней IF FOUND ...:

IF EXISTS (
    SELECT 1 
    FROM pref_scores p1 
    JOIN pref_scores p2 USING (gid) 
    WHERE p1.id = 'OK261593357402' 
    AND p2.id = 'MR3689735717800138910' 
    ) THEN 
    -- do stuff 
END IF; 

Вам не нужна таблица pref_games, чтобы ответить на ваш вопрос.

+0

Спасибо! И вы правы в том, что таблица 'pref_games' не нужна, очень проницательна :-) –

1
select pg.*, ps.id, ps2.id 
from 
    pref_games pg 
    inner join 
    pref_scores ps on pg.gid = ps.gid 
    inner join 
    pref_scores ps2 on ps.gid = ps2.gid 
where 
    ps.id = 'OK261593357402' 
    and ps2.id != 'OK261593357402'