Reputation: 37
OK, another newbie SQL question which i'm sure has a simple solution and i'll kick myself when someone posts the answer!
I have two tables as follows
PRICE_DTA
PRC_DATE PRC_TIME PRC_PRICE PRC_ITEM
2008-01-01 06.00.00 1.05 JUMPER
2008-01-01 09.00.00 1.20 JUMPER
2008-01-25 17.00.00 1.75 JUMPER
2008-01-02 09.00.00 2.25 TROUSERS
2008-10-25 12.00.00 2.95 TROUSERS
SALE_DTA
TRN_DATE TRN_TIME TRN_PRICE_PAID TRN_ITEM
2008-01-01 08.30.00 JUMPER
2008-01-03 10.00.00 JUMPER
2008-01-03 17.00.00 JUMPER
2008-01-01 13.00.00 TROUSERS
2008-01-02 09.00.00 TROUSERS
The way the prices work is that you get the NEXT available price(prices aren't set until after the purchase because we bulk all the orders up and get a cheaper price the more we buy in one go). So, in the example the 08.30.00 purchase on 2008-01-01 will have been for 1.20 because that is the first available price after the purchase date/time
So, I need to populate the prices in the SALE_DTA table using the TRN_DATE/TRN_TIME fields to go an get the next available price off the PRICE_DTA tables. NOTE: The DATE and TIME fields on both tables are CHAR fields not date/timestamp fields
I can concatenate the date and time easily enough but i'm not sure how to find the FIRST record on PRICE_DTA with a date/time stamp greater than that. I know on UNISYS DMS II I can use a 'FIND NEXT GREATER THAN' but can't find a similar command in SQL?
I'm happy to create a temporary table as part of the solution if that makes it simpler.
Upvotes: 1
Views: 2316
Reputation: 77876
You can certainly get the data required but DB2 don't support JOIN
with UPDATE
statement. So you can take a different route like
Create a auxiliary table
create table SALE_DTA_temp(TRN_DATE,TRN_TIME,TRN_PRICE_PAID,TRN_ITEM)
Do a insert into temp table from the query
insert into SALE_DTA_temp
select sd.TRN_DATE,
sd.TRN_TIME,
tab.max_PRC_PRICE as TRN_PRICE_PAID,
sd.TRN_ITEM
from SALE_DTA sd
join
(
select PRC_DATE, max(PRC_PRICE) as max_PRC_PRICE
from PRICE_DTA
group by PRC_DATE
) tab on sd.TRN_DATE = tab.PRC_DATE
Drop the old table
drop table SALE_DTA
Rename the table
RENAME TABLE SALE_DTA_temp TO SALE_DTA
Upvotes: 0
Reputation: 239704
The generic SQL solution for this can be done with a couple of joins:
SELECT
* --TODO - Pick appropriate columns
FROM
SALE_DTA s
INNER JOIN
PRICE_DTA p
ON
p.PRC_ITEM = s.TRN_ITEM and
(p.PRC_DATE > s.TRN_DATE or
(p.PRC_DATE = s.TRN_DATE and
p.PRC_TIME > s.TRN_TIME
))
LEFT JOIN
PRICE_DTA p2
ON
p2.PRC_ITEM = s.TRN_ITEM and
(p2.PRC_DATE > s.TRN_DATE or
(p2.PRC_DATE = s.TRN_DATE and
p2.PRC_TIME > s.TRN_TIME
)) and
(p2.PRC_DATE < p.PRC_DATE or
(p2.PRC_DATE = p.PRC_DATE and
p2.PRC_TIME < p.PRC_TIME
))
WHERE
p2.PRC_ITEM IS NULL
Hopefully, you can see the logic here. The INNER JOIN
is used to match rows in SALE_DTA
with all rows in PRICE_DTA
that occur afterwards. We then do a second join (the LEFT JOIN
) to this PRICE_DTA
again, this time trying to locate a row with this join (p2
) such that it still occurs after the s
date/time, but occurs before the p
date/time.
Finally, in the WHERE
clause, we eliminate any rows where this LEFT JOIN
actually succeeded. Therefore, by deduction, we know that the row that we matched in p
is the earliest row from PRICE_DTA
which occurs after the SALE_DTA
date/time.
Upvotes: 2