Re: [SQL] master/detail

2012-05-21 Thread Mario Dankoor

On 2012-05-21 1:17 AM, Jan Bakuwel wrote:

Hi,

I'm trying to get my head around the following question. As an example
take a table with products:

productid (pk)
name

and productprice

productpriceid (pk)
productid (fk)
pricedate
price

There are multiple records in productprice for each product as prices
(often) go up and (less often) go down.

I'm looking for a query that returns the following:

productid, name, pricedate, current_price, difference

current_price is the latest (ie. most recent date) price of the product
and difference is the difference in price between the latest price and
the price before the latest.

Any suggestions how to do this with SQL only? I can make it work with a
function (probably less efficient) but think this should be possible
with SQL too...

cheers,
Jan



With windowing functions:

select  FRS.name
   ,FRS.productprice  as current_price
   ,FRS.productprice- NXT.productprice
from
(
SELECT PRC.productid
   ,PRC.productprice
   ,ROW_NUMBER() OVER(PARTITION BY PRC.productid ORDER BY 
PRC.pricedate desc) rank_nr

FROM  productprice PRC
 ,products PRD
WHERE 1 = 1
AND PRD.productid = PRC.productid
) FRS
LEFT JOIN
(
SELECT  productid
   ,productprice
   ,ROW_NUMBER() OVER(PARTITION BY productid ORDER BY pricedate 
desc) rank_nr

FROM productprice
) NXT
ON FRS.productid = NXT.productid
AND NXT.rank_nr < 3
AND FRS.rank_nr <> NXT.rank_nr
WHERE 1 = 1
AND FRS.rank_nr = 1

Without windowing functions (slightly complicated, it's merely a max-mix 
issue and assuming that the date includes the time)


SELECT  CUR.name
   ,CUR.productid
   ,CUR.current_price
   ,CUR.current_price - PRV.previous_price price_difference
FROM ( --LATEST PRICE
SELECT PRD.name
  ,PRC.productid
,PRC.productprice current_price
   FROM  productprice PRC
 ,products PRD
 ,(--LATEST PRICEDATE
SELECT  productid
   ,MAX(pricedate) pricedate
FROM productprice
GROUP BY productid
) MMX
WHERE 1 = 1
AND PRC.productid = PRD.productid
AND PRC.productid = MMX.productid
AND PRC.pricedate = MMX.pricedate
 )CUR
-- IN CASE THERE'S NO PREVIOUS PRICE
LEFT JOIN
(  -- PREVIOUS PRICE
SELECT  PRC.productid
   ,PRC.productprice previous_price
FROM  productprice PRC
 ,(--PREVIOUS PRICEDATE
   SELECT PRC.productid
   ,MAX(PRC.pricedate) pricedate
FROM  productprice PRC
 ,(
SELECT  productid
   ,MAX(pricedate) pricedate
FROM productprice
GROUP BY productid
) MMX
WHERE 1 = 1
AND PRC.productid = MMX.productid
AND PRC.pricedate < MMX.pricedate
  ) PRV
WHERE 1 = 1
AND PRC.productid = PRV.productid
AND PRC.pricedate = PRV.pricedate
) LST
ON CUR.productid = LST.productid

cheers

Mario


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


[SQL] Select every first/last record of a partition?

2012-05-21 Thread Andreas

Hi,

suppose a table that has records with some ID and a timestamp.

id,ts
3,2012/01/03
5,2012/01/05
7,2012/01/07
3,2012/02/03
3,2012/01/05
5,2012/03/01
7,2012/04/04

to fetch every last row of those IDs I do:

select   id, ts
from   (   select   id, ts, row_number() over ( partition by id   order 
by ts desc ) as nr from mytab ) as x

where nr = 1


Is there a another way without a subselect?
There might be more columns so the window-functions first/last won't help.




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


Re: [SQL] Select every first/last record of a partition?

2012-05-21 Thread Seth Gordon
I think this would work:

select distinct on (id) id, ts --and whatever other columns you want
from mytab
order by id, timestamp desc;

On Mon, May 21, 2012 at 12:04 PM, Andreas  wrote:
> Hi,
>
> suppose a table that has records with some ID and a timestamp.
>
> id,    ts
> 3,    2012/01/03
> 5,    2012/01/05
> 7,    2012/01/07
> 3,    2012/02/03
> 3,    2012/01/05
> 5,    2012/03/01
> 7,    2012/04/04
>
> to fetch every last row of those IDs I do:
>
> select   id, ts
> from   (   select   id, ts, row_number() over ( partition by id   order by
> ts desc ) as nr from mytab ) as x
> where nr = 1
>
>
> Is there a another way without a subselect?
> There might be more columns so the window-functions first/last won't help.
>
>
>
>
> --
> Sent via pgsql-sql mailing list ([email protected])
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-sql

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