Re: [SQL] SQL Subqueries on each result row

2009-09-24 Thread Mark J Camilleri
On Wed, Sep 23, 2009 at 6:33 PM, Jim  wrote:

> On Sep 23, 5:43 am, AnthonyV  wrote:
> > Hello,
> >
> > I have a table like :
> >
> >date|value
> > ---
> > 2009-09-19 |  1
> > 2009-09-20 |  2
> > 2009-09-21 |  6
> > 2009-09-22 |  9
> > 2009-09-23 |  1
> >
> > I'd like a request which gives me the sum of each last n days.
> > For example, if I want the sum of each 3 days, I want this result:
> >
> >date| sum_value
> > ---
> > 2009-09-19 |  1   (sum from 2009-09-17 to 2009-09-19)
> > 2009-09-20 |  3   (sum from 2009-09-18 to 2009-09-20)
> > 2009-09-21 |  9   (sum from 2009-09-19 to 2009-09-21)
> > 2009-09-22 |  17   (sum from 2009-09-20 to 2009-09-22)
> > 2009-09-23 |  16   (sum from 2009-09-21 to 2009-09-23)
> >
> > I try to make a subquery which is apply on each row of a query, but it
> > does work.
> >
> > Has anybody an idea?
> >
> > Thanks in advance!
> >
> > Anthony
>
> How about the following?
>
> BEGIN ;
>
> CREATE TABLE z (
>  the_date   date not null
>  ,value  integer not null
> ) ;
>
> INSERT INTO z VALUES('2009-09-19',1) ;
> INSERT INTO z VALUES('2009-09-20',2) ;
> INSERT INTO z VALUES('2009-09-21',6) ;
> INSERT INTO z VALUES('2009-09-22',9) ;
> INSERT INTO z VALUES('2009-09-23',1) ;
>
> SELECT z.the_date, SUM(z2.value)
>  FROM z
>   LEFT JOIN z z2
>   ON z2.the_date IN (
>  z.the_date
> ,z.the_date-'1 day'::interval
> ,z.the_date-'2 day'::interval
> )
>  GROUP BY 1
>  ORDER BY 1
> ;
>
> ROLLBACK ;
>
> output:
>
>  the_date  | sum
> +-
>  2009-09-19 |   1
>  2009-09-20 |   3
>  2009-09-21 |   9
>  2009-09-22 |  17
>  2009-09-23 |  16
> (5 rows)
>
> --
> Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-sql
>

Hi,

The only problem that crops to mind with the above solution is that it
assumes that the dates will always be contiguous...well to be fair the
original request did not mention otherwise either!.. in any case the
solution below should work also with non-consecutive dates.  I am afraid
though that it might be a hogger with larger datasets - I just tried out the
first idea that hit me, so use with caution.


CREATE TABLE index_dates AS
SELECT--The result of this is a relation with the dates, values and
'index numbers' - placed in a temp table (you may also create
a view instead so that it is updated all the time - your call)
z.the_date, z.value, z3.indx
FROM
z,
( SELECT--This select generates the 'index number' for each
date, 1 being assigned to the smallest date
z2.the_date, count(z.the_date) AS indx
FROM
z,
z AS z2
WHERE
z.the_date <= z2.the_date
GROUP BY
z2.the_date ) AS z3
WHERE
z.the_date = z3.the_date;


SELECT--same query as suggested by Jim but run on the temp table and
joined on the index numbers instead of dates
index_dates.the_date, sum(z2.value)
FROM
index_dates
LEFT JOIN index_dates z2
ON z2.indx IN (index_dates.indx, index_dates.indx-1, index_dates.indx-2)
GROUP BY index_dates.the_date
ORDER BY index_dates.the_date;


DROP TABLE index_dates;


RESULT:

DATE| SUM
---
2009-09-19|1
2009-09-20|3
2009-09-21|9
2009-09-24|17{inserted instead of 22 Sep}
2009-10-25|16{inserted instead of 23 Sep}

Regs,
Mark


[SQL] simple (?) join

2009-09-24 Thread Gary Stainburn
Hi folks.

I have two tables

create table orders (
o_id serial primary key
...
);

create table orders_log (
ol_id serial primary key,
o_id int4 not null references orders(o_id),
ol_timestamp timestamp,
ol_user,
);

How can I select all from orders and the last (latest) entry from the 
orders_log?

Cheers
-- 
Gary Stainburn

Gary's Haircut 700
Please visit http://www.justgiving.com/Gary-Stainburn/ to help me 
raise money for Cancer Research - in return I'll have my head shaved
 

-- 
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql


Re: [SQL] simple (?) join

2009-09-24 Thread Oliveiros C,

You mean
to list the complete orders table and for each of its records, the 
corresponding record on the orders_log with the latest ol_timestamp?



SELECT *
FROM orders_log main
JOIN
(
SELECT orders.*,  MAX(orders_log.ol_timestamp) as latest
FROM orders
NATURAL JOIN orders_log
GROUP BY orders.*
) subquery
ON main.ol_timestamp = subquery.latest
AND main.o_id = subquery.o_id

This query is untested, but could you give it a try?

Then tell me the results.

NB - I am not sure if it is legal to use * on a GROUP BY clause, but if it 
isnt please kindly substitute by orders.o_id, orders.next_field, etc...


Best,
Oliveiros


- Original Message - 
From: "Gary Stainburn" 

To: 
Sent: Thursday, September 24, 2009 4:16 PM
Subject: [SQL] simple (?) join



Hi folks.

I have two tables

create table orders (
o_id serial primary key
...
);

create table orders_log (
ol_id serial primary key,
o_id int4 not null references orders(o_id),
ol_timestamp timestamp,
ol_user,
);

How can I select all from orders and the last (latest) entry from the
orders_log?

Cheers
--
Gary Stainburn

Gary's Haircut 700
Please visit http://www.justgiving.com/Gary-Stainburn/ to help me
raise money for Cancer Research - in return I'll have my head shaved


--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql 



--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql


Re: [SQL] simple (?) join

2009-09-24 Thread Oliveiros C,

Hmm...no, it seems, it is not allowable to
use orders.* on a
GROUP BY clause.

Unless you've defined for the table something called an ordering operator.

If you didn't, you'll have to include all the fields from the orders table 
in the GROUP BY clause


HTH

Best,
Oliveiros

- Original Message - 
From: "Oliveiros C," 
To: "Gary Stainburn" ; 


Sent: Thursday, September 24, 2009 6:17 PM
Subject: Re: [SQL] simple (?) join



You mean
to list the complete orders table and for each of its records, the 
corresponding record on the orders_log with the latest ol_timestamp?



SELECT *
FROM orders_log main
JOIN
(
SELECT orders.*,  MAX(orders_log.ol_timestamp) as latest
FROM orders
NATURAL JOIN orders_log
GROUP BY orders.*
) subquery
ON main.ol_timestamp = subquery.latest
AND main.o_id = subquery.o_id

This query is untested, but could you give it a try?

Then tell me the results.

NB - I am not sure if it is legal to use * on a GROUP BY clause, but if it 
isnt please kindly substitute by orders.o_id, orders.next_field, etc...


Best,
Oliveiros


- Original Message - 
From: "Gary Stainburn" 

To: 
Sent: Thursday, September 24, 2009 4:16 PM
Subject: [SQL] simple (?) join



Hi folks.

I have two tables

create table orders (
o_id serial primary key
...
);

create table orders_log (
ol_id serial primary key,
o_id int4 not null references orders(o_id),
ol_timestamp timestamp,
ol_user,
);

How can I select all from orders and the last (latest) entry from the
orders_log?

Cheers
--
Gary Stainburn

Gary's Haircut 700
Please visit http://www.justgiving.com/Gary-Stainburn/ to help me
raise money for Cancer Research - in return I'll have my head shaved


--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql



--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql 



--
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql


Re: [SQL] simple (?) join

2009-09-24 Thread David W Noon
On Thu, 24 Sep 2009 16:16:36 +0100, Gary Stainburn wrote about [SQL]
simple (?) join:

>create table orders (
>o_id serial primary key
>...
>);
>
>create table orders_log (
>ol_id serial primary key,
>o_id int4 not null references orders(o_id),
>ol_timestamp timestamp,
>ol_user,
>);
>
>How can I select all from orders and the last (latest) entry from the 
>orders_log?

SELECT * FROM orders
WHERE o_id IN (SELECT o_id FROM orders_log
   WHERE ol_timestamp = (SELECT MAX(ol_timestamp) FROM orders_log));

No joins required.
-- 
Regards,

Dave  [RLU #314465]
===
david.w.n...@ntlworld.com (David W Noon)
===

-- 
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql


Re: [SQL] simple (?) join

2009-09-24 Thread justin






David W Noon wrote:

  On Thu, 24 Sep 2009 16:16:36 +0100, Gary Stainburn wrote about [SQL]
simple (?) join:

  
  
create table orders (
o_id serial primary key
...
);

create table orders_log (
ol_id serial primary key,
o_id int4 not null references orders(o_id),
ol_timestamp timestamp,
ol_user,
);

How can I select all from orders and the last (latest) entry from the 
orders_log?

  
  
SELECT * FROM orders
WHERE o_id IN (SELECT o_id FROM orders_log
   WHERE ol_timestamp = (SELECT MAX(ol_timestamp) FROM orders_log));

No joins required.
  


I don't think that is what he is requesting.  I read it he also wants
the timestamp included in the result set

A nested query 

Select 
    orders.*, 
    (SELECT MAX(ol_timestamp) FROM orders_log where orders_log.o_id =
orders.oid) 
>From orders

Still another option is using a join 

Select 
    orders.*, ol_timestamp
    From orders 
    left join (SELECT MAX(ol_timestamp), o_id FROM orders_log group by
o_id) as JoinQuery on JoinQuery.o_id = orders.o_id 

The second one should be faster







Re: [SQL] simple (?) join

2009-09-24 Thread David W Noon
On Thu, 24 Sep 2009 16:15:07 -0400, justin wrote about Re: [SQL] simple
(?) join:

>
>
>David W Noon wrote:On Thu, 24 Sep 2009 16:16:36 +0100, Gary Stainburn
>wrote about [SQL] simple (?) join:
>
>  create table orders (
>o_id serial primary key
>...
>);
>
>create table orders_log (
>ol_id serial primary key,
>o_id int4 not null references orders(o_id),
>ol_timestamp timestamp,
>ol_user,
>);
>
>How can I select all from orders and the last (latest) entry from the 
>orders_log?
>
>SELECT * FROM orders
>WHERE o_id IN (SELECT o_id FROM orders_log
>   WHERE ol_timestamp = (SELECT MAX(ol_timestamp) FROM orders_log));
>
>No joins required.
>  
>I don't think that is what he is requesting.  I read it he also wants
>the timestamp included in the result set

That shouldn't be too much of a problem.

>A nested query
>
>Select
>orders.*,
>(SELECT MAX(ol_timestamp) FROM orders_log where orders_log.o_id =
> orders.oid)
>From orders

That won't give the desired results. I don't think the SQL parser will
even accept it.

>Still another option is using a join
>
>Select
>orders.*, ol_timestamp
>From orders
>left join (SELECT MAX(ol_timestamp), o_id FROM orders_log group by
> o_id) as JoinQuery on JoinQuery.o_id = orders.o_id

That won't give the desired results either. If you change "left" to
"inner" you will be closer though.

Both of your queries will retrieve the entire orders table with a
timestamp of some sort from the orders_log table.

>The second one should be faster

Try this for an elegant approach:

WITH maxi AS (SELECT MAX(ol_timestamp) AS ts FROM orders_log)
SELECT o.*, maxi.ts
FROM orders AS o
WHERE o.o_id IN (SELECT o_id FROM orders_log
   WHERE ol_timestamp = maxi.ts);

This caches the latest timestamp in a temporary table so that it can
both appear in the result set and be used to constrain the selection
from the orders_log table.
-- 
Regards,

Dave  [RLU #314465]
===
david.w.n...@ntlworld.com (David W Noon)
===

-- 
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql


Re: [SQL] simple (?) join

2009-09-24 Thread Raj Mathur
On Thursday 24 Sep 2009, Gary Stainburn wrote:
> Hi folks.
> 
> I have two tables
> 
> create table orders (
> o_id serial primary key
> ...
> );
> 
> create table orders_log (
> ol_id serial primary key,
> o_id int4 not null references orders(o_id),
> ol_timestamp timestamp,
> ol_user,
> );
> 
> How can I select all from orders and the last (latest) entry from the
> orders_log?

Does this do what you want?  You would have to do some tricks if you 
also want orders that don't have any entry in the orders_log table to be 
displayed.

select ol.ol_id,ol.o_id,ol.ol_timestamp
from orders o natural join orders_log ol
where (ol.o_id,ol.ol_timestamp)
  in (select o_id,max(ol_timestamp) from orders_log group by o_id);

Regards,

-- Raju
-- 
Raj Mathurr...@kandalaya.org  http://kandalaya.org/
   GPG: 78D4 FC67 367F 40E2 0DD5  0FEF C968 D0EF CC68 D17F
PsyTrance & Chill: http://schizoid.in/   ||   It is the mind that moves

-- 
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql