pg.ddx.io pgsql-sql@postgresql.org mailing list archive
help / color / mirror / Atom feedmaster/detail
5+ messages / 4 participants
[nested] [flat]
* master/detail
@ 2012-05-20 23:17 Jan Bakuwel <jan.bakuwel@greenpeace.org>
2012-05-21 03:10 ` Re: master/detail Raj Mathur (=?utf-8?b?4KSw4KS+4KSc?= =?utf-8?b?IOCkruCkvuCkpeClgeCksA==?=) <raju@linux-delhi.org>
2012-05-21 04:34 ` Re: master/detail Andreas Kretschmer <andreas@a-kretschmer.de>
2012-05-21 11:57 ` Re: master/detail Mario Dankoor <m.p.dankoor@gmail.com>
0 siblings, 3 replies; 5+ messages in thread
From: Jan Bakuwel @ 2012-05-20 23:17 UTC (permalink / raw)
To: pgsql-sql
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
Attachments:
[application/pkcs7-signature] smime.p7s (3.6K, ../../4FB97B70.6080604@greenpeace.org/2-smime.p7s)
download
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: master/detail
2012-05-20 23:17 master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
@ 2012-05-21 03:10 ` Raj Mathur (=?utf-8?b?4KSw4KS+4KSc?= =?utf-8?b?IOCkruCkvuCkpeClgeCksA==?=) <raju@linux-delhi.org>
2 siblings, 0 replies; 5+ messages in thread
From: Raj Mathur (राज माथुर) @ 2012-05-21 03:10 UTC (permalink / raw)
To: pgsql-sql
On Monday 21 May 2012, 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...
Something like this ought to do it (not tested):
select latest.price, latest.price - next.price
from
(select price from productprice where productid = 1
order by pricedate desc limit 1) latest,
(select price from productprice where productid = 1
order by pricedate desc limit 2 offset 1) next;
Regards,
-- Raj
--
Raj Mathur || raju@kandalaya.org || GPG:
http://otheronepercent.blogspot.com || http://kandalaya.org || CC68
It is the mind that moves || http://schizoid.in || D17F
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: master/detail
2012-05-20 23:17 master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
@ 2012-05-21 04:34 ` Andreas Kretschmer <andreas@a-kretschmer.de>
2012-05-22 07:28 ` Re: master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
2 siblings, 1 reply; 5+ messages in thread
From: Andreas Kretschmer @ 2012-05-21 04:34 UTC (permalink / raw)
To: Jan Bakuwel <jan.bakuwel@greenpeace.org>; pgsql-sql
Jan Bakuwel <jan.bakuwel@greenpeace.org> hat am 21. Mai 2012 um 01:17
geschrieben:
> 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...
You can use window-function, in your case something like:
test=# select * from productprice ;
id | product | pricedate | price
----+---------+------------+-------
1 | 1 | 2012-05-01 | 10
2 | 1 | 2012-05-05 | 15
3 | 1 | 2012-05-10 | 12
4 | 1 | 2012-05-15 | 22
(4 rows)
test=*# select id, product, pricedate, price, lead(price) over (partition by
product order by pricedate desc), price - (lead(price) over (partition by
product order by pricedate desc)) from productprice;
id | product | pricedate | price | lead | ?column?
----+---------+------------+-------+------+----------
4 | 1 | 2012-05-15 | 22 | 12 | 10
3 | 1 | 2012-05-10 | 12 | 15 | -3
2 | 1 | 2012-05-05 | 15 | 10 | 5
1 | 1 | 2012-05-01 | 10 | |
(4 rows)
Regards, Andreas
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: master/detail
2012-05-20 23:17 master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
2012-05-21 04:34 ` Re: master/detail Andreas Kretschmer <andreas@a-kretschmer.de>
@ 2012-05-22 07:28 ` Jan Bakuwel <jan.bakuwel@greenpeace.org>
0 siblings, 0 replies; 5+ messages in thread
From: Jan Bakuwel @ 2012-05-22 07:28 UTC (permalink / raw)
To: pgsql-sql
Hi Andreas and Mario,
Many thanks for your suggestion to use PostgreSQL's window function,
exactly what I needed.
kind regards,
Jan
Attachments:
[application/pkcs7-signature] smime.p7s (3.6K, ../../4FBB4027.1030609@greenpeace.org/2-smime.p7s)
download
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: master/detail
2012-05-20 23:17 master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
@ 2012-05-21 11:57 ` Mario Dankoor <m.p.dankoor@gmail.com>
2 siblings, 0 replies; 5+ messages in thread
From: Mario Dankoor @ 2012-05-21 11:57 UTC (permalink / raw)
To: pgsql-sql
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
^ permalink raw reply [nested|flat] 5+ messages in thread
end of thread, other threads:[~2012-05-22 07:28 UTC | newest]
Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2012-05-20 23:17 master/detail Jan Bakuwel <jan.bakuwel@greenpeace.org>
2012-05-21 03:10 ` Raj Mathur (=?utf-8?b?4KSw4KS+4KSc?= =?utf-8?b?IOCkruCkvuCkpeClgeCksA==?=) <raju@linux-delhi.org>
2012-05-21 04:34 ` Andreas Kretschmer <andreas@a-kretschmer.de>
2012-05-22 07:28 ` Jan Bakuwel <jan.bakuwel@greenpeace.org>
2012-05-21 11:57 ` Mario Dankoor <m.p.dankoor@gmail.com>
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