Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id A1F7CA684E0 for ; Mon, 21 May 2012 08:57:40 -0300 (ADT) Received: from mail-bk0-f46.google.com ([209.85.214.46]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1SWRF4-0004nP-9A for pgsql-sql@postgresql.org; Mon, 21 May 2012 11:57:40 +0000 Received: by bkcji2 with SMTP id ji2so3868834bkc.19 for ; Mon, 21 May 2012 04:57:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=gpDzobGAf5nC72IVqzSavtGKQr3WLgDlNiIZhe2AD58=; b=W2zF+Ull/LnwHrqoX0clXMgoviybDk+W2WYQaGe8ht/GItDIfTDSSkMI8Xc1NTaMsI tCeVVAuCkuij//Ed0rjaZPfPZJk6QdEtA7FzI7Bzs/VckMxPM6Km7Z+HJpIbLG1zYuY/ gXFBYLPUiT3wx83ixrixD6+5Kzi8hAewdhnI7ICVlTInMlYRnDU0PLTG0gMjrd1Fudi9 7y2qeQHfd1eELlpz49AsaAwujc9Maarrq4b7WbkjYk7Nujt2Ple+Sk4+cxJEdD/nup/w JmelkQ7BR59omdez7srNohuMobgZ2RTNz0BM8q1ghIet8B4WdJDTfEpiHzc6dEr3sfNv QPfw== Received: by 10.205.123.9 with SMTP id gi9mr987795bkc.50.1337601444906; Mon, 21 May 2012 04:57:24 -0700 (PDT) Received: from [192.168.178.16] (qtuning.xs4all.nl. [80.101.37.209]) by mx.google.com with ESMTPS id ig1sm26800320bkc.4.2012.05.21.04.57.23 (version=SSLv3 cipher=OTHER); Mon, 21 May 2012 04:57:23 -0700 (PDT) Message-ID: <4FBA2DA1.204@gmail.com> Date: Mon, 21 May 2012 13:57:21 +0200 From: Mario Dankoor User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20120428 Thunderbird/12.0.1 MIME-Version: 1.0 To: pgsql-sql@postgresql.org Subject: Re: master/detail References: <4FB7EEC6.1030004@gmx.net> <4FB8B489.3050701@gmx.net> <4FB97B70.6080604@greenpeace.org> In-Reply-To: <4FB97B70.6080604@greenpeace.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.6 (--) X-Archive-Number: 201205/57 X-Sequence-Number: 36605 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