Complex join query - Mailing list pgsql-admin

From Gareth Kirwan
Subject Complex join query
Date
Msg-id 001b01c20718$990f1ff0$55eaa8c0@gbjk1
Whole thread Raw
In response to Re: Problems in query  (Masaru Sugawara <rk73@sea.plala.or.jp>)
Responses Re: Complex join query
List pgsql-admin
Hello all,
    Let's dive straight in, eh?

1.
    Table: current_sessions
    Fields: Server (int Foreign Key servers.id)
    Client (int Foreign Key clients.id)
    status (vc(10))

2.
    Table: clients
    Fields: id (serial Pkey)
    username (UNIQUE)

3.
    Table: servers
    Fields: id (serial Pkey)
    username (UNIQUE)

Normally, the username of the client should come from the clients table,
hence you'd inner join plainly.
IF the status is 'ADMIN' however - it means both the server and the client
come from the servers table.

HOW ( if at all ) can I pull this off in a join without having to
restructure the tables?
This is what I did have:

SELECT cs.id, s.username AS Server, c.username AS
Client from current_sessions cs INNER JOIN clients c ON (cs.client=c.id)
INNER JOIN servers s ON (cs.server=s.id) where cs.status!='AVAIL' AND
((cs.server=1) OR (cs.client=1 AND cs.status='ADMIN'));

but that obviously wouldn't work!!!
SO, I tried a where version:

SELECT cs.id, s.username, username from current_sessions cs, clients c,
servers s
where ((cs.status=='AVAIL') AND (cs.client = c.id)) OR ((cs.status=='ADMIN')
AND (cs.client = s.id));

but this obviously returns an ambiguous username error - it's not
intelligent enough to decide that that username should be pulled from the
condition at the end - understandably!

AND FINALLY:

Kind of a solution:
code:
----------------------------------------------------------------------------
----
SELECT
      cs.id,
      s.username AS ServerA,
      sb.username AS ServerB,
      c.username AS Client,
      cs.status
 from current_sessions cs
   INNER JOIN clients c ON (cs.client=c.id)
   INNER JOIN servers s ON (cs.server=s.id)
   INNER JOIN servers sb ON (cs.client=sb.id)
 where   cs.status != 'AVAIL'
     AND
        (
         (cs.server=1)
        )
     OR
        (
         (cs.client=1 AND cs.status='ADMIN')
        );
----------------------------------------------------------------------------
----

And this produces:

    id  | servera | serverb | client | status
    ----+---------+---------+--------+-------
    645 | pco     | rrg     | mpo    | CONV
    650 | rrg     | pco     | gbjk   | ADMIN

Which then gives:

    id  | Server | client
    ----+---------+------
    645 | pco     | mpo
    650 | rrg     | pco

because NORMALLY the client is the client -
BUT if the status is ADMIN then the client is the second server.

Now this is as close as I can get it...
I can use the server side language to handle the output
from this... but bearing in mind that I'm using
Postgresql Functions (plpgsql) - and opening a cursor for this select before
returning it ..

Is there anything I can do after this to make the Second output table i've
shown (id, server, client) from the first one (id, server, serverb, client,
status) given the clause that the client of the first table should be the
client in the second - UNLESS
the status of the first table is ADMIN - in which case the client of the
second is the serverb from the first.

make sense?

i hope so.

Thanks everyone

Gareth Kirwan
Programming & Development
Thermeon Europe Ltd
+44 1293 864 303
gbjk@thermeoneurope.com



pgsql-admin by date:

Previous
From: "Nick Fankhauser"
Date:
Subject: Re: how to install postgresql!!
Next
From: bangh
Date:
Subject: Re: how to install postgresql!!