pg.ddx.io pgsql-sql@postgresql.org mailing list archive
help / color / mirror / Atom feedSQL Newbie
6+ messages / 5 participants
[nested] [flat]
* SQL Newbie
@ 2005-08-12 15:09 Lane Van Ingen <lvaningen@esncc.com>
0 siblings, 3 replies; 6+ messages in thread
From: Lane Van Ingen @ 2005-08-12 15:09 UTC (permalink / raw)
To: pgsql-sql
It seems to me that I should be able to do this, but after 5 hrs of trying,
I
can't figure this one out.
I could do this in two queries, but seems like I should be able to do this
in
one. What I am trying to do:
Find the highest speed at which each interface of a router has run over
time.
I have three tables, two of which (interface, speed_history) are being used
in
this query (primary / foreign key fields noted as PK / FK):
router -> 1:M -> interface -> 1:M -> speed_history
------------------- --------------------------- --------------------------
-
router_no (int2) PK interface_id (int4) PK interface_id (int4) PK
name (varchar) router_no (int2) FK updated_time (timestamp)
PK
link_description (varchar) speed (int4)
Data in speed history looks like this:
interface_id updated_time speed
1 2005-08-11 08:10:23 450112
1 2005-08-11 10:53:34 501120 <---
1 2005-08-11 10:58:11 450112
2 2005-08-11 08:10:23 450112 <---
2 2005-08-11 11:00:44 350234
3 2005-08-11 08:10:23 450112 <---
The rows of speed_history I want back are marked above with ' <--- '.
Query results should look like:
interface.interface_id
interface.link_description
speed_history.updated_time
speed_history.speed
^ permalink raw reply [nested|flat] 6+ messages in thread
* Re: SQL Newbie
@ 2005-08-12 16:02 Sean Davis <sdavis2@mail.nih.gov>
parent: Lane Van Ingen <lvaningen@esncc.com>
2 siblings, 0 replies; 6+ messages in thread
From: Sean Davis @ 2005-08-12 16:02 UTC (permalink / raw)
To: Lane Van Ingen <lvaningen@esncc.com>; pgsql-sql
On 8/12/05 11:09 AM, "Lane Van Ingen" <lvaningen@esncc.com> wrote:
> It seems to me that I should be able to do this, but after 5 hrs of trying,
> I
> can't figure this one out.
>
> I could do this in two queries, but seems like I should be able to do this
> in
> one. What I am trying to do:
> Find the highest speed at which each interface of a router has run over
> time.
>
> I have three tables, two of which (interface, speed_history) are being used
> in
> this query (primary / foreign key fields noted as PK / FK):
>
> router -> 1:M -> interface -> 1:M -> speed_history
> ------------------- --------------------------- --------------------------
> -
> router_no (int2) PK interface_id (int4) PK interface_id (int4) PK
> name (varchar) router_no (int2) FK updated_time (timestamp)
> PK
> link_description (varchar) speed (int4)
>
> Data in speed history looks like this:
> interface_id updated_time speed
> 1 2005-08-11 08:10:23 450112
> 1 2005-08-11 10:53:34 501120 <---
> 1 2005-08-11 10:58:11 450112
> 2 2005-08-11 08:10:23 450112 <---
> 2 2005-08-11 11:00:44 350234
> 3 2005-08-11 08:10:23 450112 <---
> The rows of speed_history I want back are marked above with ' <--- '.
>
> Query results should look like:
> interface.interface_id
> interface.link_description
> speed_history.updated_time
> speed_history.speed
What about (untested):
SELECT a.interface_id,
a.link_description,
c.updated_time,
c.speed
FROM
interface a,
(select interface_id,max(speed) as speed
from speed_history,interface group by interface_id) as b,
speed_history c
WHERE
b.interface_id=a.interface_id AND
c.speed=b.speed;
Sean
^ permalink raw reply [nested|flat] 6+ messages in thread
* Re: SQL Newbie
@ 2005-08-12 17:57 Nick Stone <nick@harelane.com>
parent: Lane Van Ingen <lvaningen@esncc.com>
2 siblings, 2 replies; 6+ messages in thread
From: Nick Stone @ 2005-08-12 17:57 UTC (permalink / raw)
To: 'Lane Van Ingen' <lvaningen@esncc.com>; pgsql-sql
Hope this helps
SELECT
*
FROM
speed_history as outside etc..
WHERE
(speed = (
SELECT
speed
FROM
speed_history as inside etc..
WHERE
(outside.interface = inside.interface)
LIMIT 1
ORDER BY
speed DESC
)
)
Hopefully you get the idea - basically it's a corelated sub-query - very
useful
Nick
-----Original Message-----
From: pgsql-sql-owner@postgresql.org [mailto:pgsql-sql-owner@postgresql.org]
On Behalf Of Lane Van Ingen
Sent: 12 August 2005 16:09
To: pgsql-sql@postgresql.org
Subject: [SQL] SQL Newbie
It seems to me that I should be able to do this, but after 5 hrs of trying,
I can't figure this one out.
I could do this in two queries, but seems like I should be able to do this
in one. What I am trying to do:
Find the highest speed at which each interface of a router has run over
time.
I have three tables, two of which (interface, speed_history) are being used
in this query (primary / foreign key fields noted as PK / FK):
router -> 1:M -> interface -> 1:M -> speed_history
------------------- --------------------------- --------------------------
-
router_no (int2) PK interface_id (int4) PK interface_id (int4) PK
name (varchar) router_no (int2) FK updated_time (timestamp)
PK
link_description (varchar) speed (int4)
Data in speed history looks like this:
interface_id updated_time speed
1 2005-08-11 08:10:23 450112
1 2005-08-11 10:53:34 501120 <---
1 2005-08-11 10:58:11 450112
2 2005-08-11 08:10:23 450112 <---
2 2005-08-11 11:00:44 350234
3 2005-08-11 08:10:23 450112 <---
The rows of speed_history I want back are marked above with ' <--- '.
Query results should look like:
interface.interface_id
interface.link_description
speed_history.updated_time
speed_history.speed
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster
^ permalink raw reply [nested|flat] 6+ messages in thread
* Re: SQL Newbie
@ 2005-08-12 18:04 Bruno Wolff III <bruno@wolff.to>
parent: Lane Van Ingen <lvaningen@esncc.com>
2 siblings, 0 replies; 6+ messages in thread
From: Bruno Wolff III @ 2005-08-12 18:04 UTC (permalink / raw)
To: Lane Van Ingen <lvaningen@esncc.com>; +Cc: pgsql-sql
> Data in speed history looks like this:
> interface_id updated_time speed
> 1 2005-08-11 08:10:23 450112
> 1 2005-08-11 10:53:34 501120 <---
> 1 2005-08-11 10:58:11 450112
> 2 2005-08-11 08:10:23 450112 <---
> 2 2005-08-11 11:00:44 350234
> 3 2005-08-11 08:10:23 450112 <---
> The rows of speed_history I want back are marked above with ' <--- '.
>
> Query results should look like:
> interface.interface_id
> interface.link_description
> speed_history.updated_time
> speed_history.speed
The main idea is to join a select of max speeds grouped by interface_id
to the interface table.
If the query runs too slow, then you may get better performance having an
index on (interface_id, speed) and using subselects. In this case
you want to select information about all of interfaces and then have
one of the columns be a subselect that selects one (using limit) speed
from rows that have a matching interface_id ordered by interface_id desc,
speed desc. This combination of limit and order by will be faster than
using max.
^ permalink raw reply [nested|flat] 6+ messages in thread
* Re: SQL Newbie
@ 2005-08-12 18:05 Owen Jacobson <ojacobson@osl.com>
parent: Nick Stone <nick@harelane.com>
1 sibling, 0 replies; 6+ messages in thread
From: Owen Jacobson @ 2005-08-12 18:05 UTC (permalink / raw)
To: pgsql-sql
Nick Stone wrote:
> Hope this helps
>
> SELECT
> *
> FROM
> speed_history as outside etc..
> WHERE
> (speed = (
> SELECT
> speed
> FROM
> speed_history as inside etc..
> WHERE
> (outside.interface = inside.interface)
> LIMIT 1
> ORDER BY
> speed DESC
> )
> )
Worth noting that ORDER BY speed DESC LIMIT 1 is fundamentally the same as
MAX (speed), except that MAX (speed) doesn't take advantage of any index
present. This is a fairly common idiom but a self-described SQL Newbie may
not see the equivalence instantly.
-Owen
^ permalink raw reply [nested|flat] 6+ messages in thread
* Re: SQL Newbie
@ 2005-08-12 19:39 Bruno Wolff III <bruno@wolff.to>
parent: Nick Stone <nick@harelane.com>
1 sibling, 0 replies; 6+ messages in thread
From: Bruno Wolff III @ 2005-08-12 19:39 UTC (permalink / raw)
To: Nick Stone <nick@harelane.com>; +Cc: Lane Van Ingen <lvaningen@esncc.com>; pgsql-sql
On Fri, Aug 12, 2005 at 18:57:34 +0100,
Nick Stone <nick@harelane.com> wrote:
> Hope this helps
>
> SELECT
> *
> FROM
> speed_history as outside etc..
> WHERE
> (speed = (
> SELECT
> speed
> FROM
> speed_history as inside etc..
> WHERE
> (outside.interface = inside.interface)
> LIMIT 1
> ORDER BY
> speed DESC
> )
> )
>
> Hopefully you get the idea - basically it's a corelated sub-query - very
> useful
>
Note that you want to order by interface DESC, speed DESC in the subselect
and have an index on (interface, speed) for this to really be efficient.
I think 8.1 might be smart enough to use an index on (interface, speed)
in the above case, but currently released versions won't.
^ permalink raw reply [nested|flat] 6+ messages in thread
end of thread, other threads:[~2005-08-12 19:39 UTC | newest]
Thread overview: 6+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2005-08-12 15:09 SQL Newbie Lane Van Ingen <lvaningen@esncc.com>
2005-08-12 16:02 ` Sean Davis <sdavis2@mail.nih.gov>
2005-08-12 17:57 ` Nick Stone <nick@harelane.com>
2005-08-12 18:05 ` Owen Jacobson <ojacobson@osl.com>
2005-08-12 19:39 ` Bruno Wolff III <bruno@wolff.to>
2005-08-12 18:04 ` Bruno Wolff III <bruno@wolff.to>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox