Price on a specific date change

G

Guest

I have the following data for dates/times when the price changes of a
product....

3/19/2000 00:00 1.47
4/23/2000 15:00 1.485
5/2/2000 02:32 1.45

I then have a second table of dates/times.

3/18/2000 15:20
3/19/2000 01:00
4/23/2000 00:01
4/23/2000 15:01
5/2/2000 02:33

I have the following query which returns one date too high and consequently
the wrong price.

SELECT tblPrices.PriceDate, (SELECT top 1 DateTimeField FROM tblDateTimes
WHERE PriceDate<=DateTimeField) AS dteDate
FROM tblPrices;

What should be returned is...

3/18/2000 15:20 0 (because there is no 2nd top date)
3/19/2000 01:00 1.47
4/23/2000 00:01 1.47
4/23/2000 15:01 1.485
5/2/2000 02:33 1.45

In essence what I need is to return the 2nd top date in order to obtain the
correct price. Any help would be appreciated. Thanks in advance.
 
K

Ken Snell [MVP]

Try this:

SELECT tblDateTimes.DateTimeField, (SELECT Price FROM tblPrices
WHERE PriceDate=(SELECT Max(T.PriceDate) FROM tblPrices AS T
WHERE T.PriceDate<=tblDateTimes.DateTimeField))
FROM tblDateTimes;
 
K

Ken Snell [MVP]

Sorry.. forgot that you wanted a zero if there was no price:

SELECT tblDateTimes.DateTimeField, Nz(SELECT Price FROM tblPrices
WHERE PriceDate=(SELECT Max(T.PriceDate) FROM tblPrices AS T
WHERE T.PriceDate<=tblDateTimes.DateTimeField),0)
FROM tblDateTimes;
 
C

Chris2

SHIPP said:
I have the following data for dates/times when the price changes of a
product....

3/19/2000 00:00 1.47
4/23/2000 15:00 1.485
5/2/2000 02:32 1.45

I then have a second table of dates/times.

3/18/2000 15:20
3/19/2000 01:00
4/23/2000 00:01
4/23/2000 15:01
5/2/2000 02:33

I have the following query which returns one date too high and consequently
the wrong price.

SELECT tblPrices.PriceDate, (SELECT top 1 DateTimeField FROM tblDateTimes
WHERE PriceDate<=DateTimeField) AS dteDate
FROM tblPrices;

What should be returned is...

3/18/2000 15:20 0 (because there is no 2nd top date)
3/19/2000 01:00 1.47
4/23/2000 00:01 1.47
4/23/2000 15:01 1.485
5/2/2000 02:33 1.45

In essence what I need is to return the 2nd top date in order to obtain the
correct price. Any help would be appreciated. Thanks in advance.

Mr. Shipp,

Ok, this gets a bit complicated. :\

In places, it gets ugly. :(

But it *appears* to work. :)


Sample Tables

CREATE TABLE Products_01302005_1
(ProductID AUTOINCREMENT
,UPC DOUBLE
,ProductName TEXT(72)
,CONSTRAINT pk_Products_01302005_1 PRIMARY KEY (ProductID)
)

Sample Data

UPC NameProduct
12345678910 Chewing Gum
12345678911 Breath Mints

CREATE TABLE ProductPrices_01302005_1
(ProductID LONG
,DatePriceChange DATETIME
,Price CURRENCY
,CONSTRAINT pk_ProductPrices_01302005_1
PRIMARY KEY (ProductID, DatePriceChange)
,CONSTRAINT fk_ProductPrices_Products_01302005_1 FOREIGN KEY
(ProductID)
REFERENCES Products_01302005_1 (ProductID)
)

Sample Data
ProductID DatePriceChanged Price
1 3/19/2000 00:00 1.47
1 4/23/2000 15:00 1.485
1 5/2/2000 02:32 1.45

Note: Technically speaking, there is missing information in
ProductPrices. The period of time a product is at a price is an
Interval, and that period has a Start and an End. But the above only
records the starting time of a price in any one particular row, and so
the ending time data will have to be recreated in a trio of queries
(which is where it gets ugly).


CREATE TABLE ProductSales_01302005_1
(ProductID LONG
,DateSale DATETIME
,CONSTRAINT pk_ProductPrices_01302005_1
PRIMARY KEY (ProductID, DateSale)
,CONSTRAINT fk_ProductSales_Products_01302005_1 FOREIGN KEY
(ProductID)
REFERENCES Products_01302005_1 (ProductID)
)

Sample Data
ProductID DateSale
1 3/18/2000 15:20
1 3/19/2000 01:00
1 4/23/2000 00:01
1 4/23/2000 15:01
1 5/02/2000 02:33


Query Name: ProductPrices_01302005_1_NextDate
SELECT PP1.ProductID
,PP1.DatePriceChange
,Nz((SELECT MIN(PP2.DatePriceChange)
FROM ProductPrices_01302005_1 AS PP2
WHERE (PP2.ProductID = PP1.ProductID
AND PP2.DatePriceChange > PP1.DatePriceChange))
,DateAdd("yyyy", 99, PP1.DatePriceChange)) AS
DatePriceEnded
,PP1.Price
FROM ProductPrices_01302005_1 AS PP1

Query Name: ProductPrices_01302005_1_PrevDate
SELECT PP1.ProductID
,#01/01/1900# AS DatePriceChange
,MIN(PP1.DatePriceChange) AS DatePriceEnded
,0.0 AS Price
FROM ProductPrices_01302005_1 AS PP1
GROUP BY PP1.ProductID
,#01/01/1900#
,0.0

Query Name: ProductPrices_01302005_1_UnionDate
SELECT ProductID
,DatePriceChange
,DatePriceEnded
,Price
FROM ProductPrices_01302005_1_PrevDate
UNION ALL
SELECT ProductID
,DatePriceChange
,DatePriceEnded
,Price
FROM ProductPrices_01302005_1_NextDate

Query Name: ProductPriceWhenSold_01302005_1
SELECT PS1.ProductID
,PS1.DateSale
,PP1.Price
FROM ProductPrices_01302005_1_UnionDate AS PP1
INNER JOIN
ProductSales_01302005_1 AS PS1
ON (PP1.ProductID = PS1.ProductID)
WHERE (PS1.DateSale BETWEEN
PP1.DatePriceChange AND PP1.DatePriceEnded)


Ok, everybody together now: "All I want for Christmas is a Full Outer
Join, A Full Outer Join!". No, no, never mind me . . .


03/18/2000 15:20 0.00
03/19/2000 01:00 1.47
04/23/2000 00:01 1.47
04/23/2000 15:01 1.485
05/02/2000 02:33 1.45


Maybe someone else knows a better way. (Hint, hint . . .)


Sincerely,

Chris O.
 
K

Ken Snell [MVP]

Thanks for that catch, Chris... I initially had them in there, and deleted
them before posting.... (should I be bold and say I didn't test it before
posting? < g >).
 
C

Chris2

Ken Snell said:
Try this:

SELECT tblDateTimes.DateTimeField, (SELECT Price FROM tblPrices
WHERE PriceDate=(SELECT Max(T.PriceDate) FROM tblPrices AS T
WHERE T.PriceDate<=tblDateTimes.DateTimeField))
FROM tblDateTimes;


--

It appears I have a ways to go.


Sincerely,

Chris O.
 
C

Chris2

Ken Snell said:
Sorry.. forgot that you wanted a zero if there was no price:

SELECT tblDateTimes.DateTimeField, Nz(SELECT Price FROM tblPrices
WHERE PriceDate=(SELECT Max(T.PriceDate) FROM tblPrices AS T
WHERE T.PriceDate<=tblDateTimes.DateTimeField),0)
FROM tblDateTimes;

Ken,

The above needs a couple extra ().

SELECT tblDateTimes.DateTimeField
,Nz((SELECT Price
FROM tblPrices
WHERE PriceDate =
(SELECT Max(T.PriceDate)
FROM tblPrices AS T
WHERE T.PriceDate<=tblDateTimes.DateTimeField)),0)
FROM tblDateTimes;


Sincerely,

Chris O.
 
G

Guest

I have finally gotten the query to pull the correct pricing date. The
following query performs that task:

SELECT tblPrices.PriceDate, (SELECT max(DateTimeField) FROM tblDateTimes
WHERE DateTimeField<=PriceDate) AS dteDate
FROM tblPrices;

However, instead of pulling the DateTimeField I want to pull the price. Any
ideas on how to change the sub-query to pull the price?
 
G

Guest

Thanks so much. Had a little bit of trouble converting your query to my query
but once I slept on it your solution worked great. Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top