Question

In PostgreSQL 8.4.13 I have two tables representing card games (each with 3 players) and the score results of those games. The players are identified by id column and the games by gid:

# \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

I'm trying to find out if a player with an id='OK261593357402' has ever played with the player id='MR3689735717800138910' - so that I can allow them to grade each other at my web site.

I think I need to call a perform true on an inner join - is this correct please?

So I'm trying:

# 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
.....

But I only see the id='OK261593357402' above, i.e. I was expecting to see all his game partners too, but they are not delivered.

I've also tried:

# 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
...

Unfortunately same result...

Should I maybe just make a series of selects combined with exists in instead?

Was it helpful?

Solution

I'm trying to find out if a player with an id='OK261593357402' has ever played with the player id='MR3689735717800138910'

It's generally shorter / faster / simpler / more elegant to use IF EXISTS ... in plpgsql than PERFORM with a trailing 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;

You don't need table pref_games at all to answer your question.

OTHER TIPS

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'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top