Solved

in MySQL, how can I reference a row that is prior to another one based on the primary index?

Posted on 2013-05-31
7
248 Views
Last Modified: 2013-06-21
I have a table, full_daily_data, that has as it's PRIMARY index the columns (symbol,trade_date).

I would like to be able to reference one row that immediately precedes another

Right now, I'm looking at something like this:

update fdd1
    set fdd1.Prior_Open = fdd2.Day_Open,
          fdd1.Prior_Close = fdd2.Day_Close
    from full_daily_data fdd1
    inner join full_daily_data fdd2
    on fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY);

Open in new window


But that only works if there are no gaps in the dates, and there are.

instead of
    on fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY);

Open in new window


Is there a way to join based on the sequence of the primary index being in date order?
0
Comment
Question by:cashonly
  • 3
  • 3
7 Comments
 
LVL 23

Expert Comment

by:nemws1
ID: 39211710
Well, you want the date from this query, don't you (note the DESC)

SELECT Trade_Date
FROM full_daily_data
ORDER BY Trade_DATE DESC
LIMIT 1
;

Open in new window


Would it be safe to do something like this:

SELECT @LATEST_TRADE_DATE:=Trade_Date
FROM full_daily_data
ORDER BY Trade_DATE DESC
LIMIT 1
;

update fdd1
    set fdd1.Prior_Open = fdd2.Day_Open,
          fdd1.Prior_Close = fdd2.Day_Close
    from full_daily_data fdd1
    inner join full_daily_data fdd2
    on fdd2.Trade_Date = @LATEST_TRADE_DATE
;

Open in new window



Looking at your scenario, I'm guessing this is pretty safe.  Only only have to worry if the select statement grabs a date and somehow a new date is inserted in the microsecond before the UPDATE statement runs.
0
 
LVL 23

Expert Comment

by:nemws1
ID: 39211726
It would be nice to combine these into one statement, like this, but MySQL doesn't let you do that. ;-(

update fdd1
    set fdd1.Prior_Open = fdd2.Day_Open,
          fdd1.Prior_Close = fdd2.Day_Close
    from full_daily_data fdd1
    inner join full_daily_data fdd2
    on fdd2.Trade_Date = (SELECT Trade_Date
          FROM full_daily_data
          ORDER BY Trade_DATE DESC
          LIMIT 1
    )
;

Open in new window

0
 

Author Comment

by:cashonly
ID: 39211907
nemws1,

I was thinking about trying the select in the update... sorry to hear it doesn't work.

I'm not sure if your first solution will work. I was looking to do an update of all the data in one shot and it looks like the update would be based on a fixed trade date, not a relative one.  It has to be based on the trade_date of the row that is receiving the "Prior_" data.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 23

Assisted Solution

by:nemws1
nemws1 earned 250 total points
ID: 39211950
Ah I gotcha.  Well, there's still a solution.  You could create a FUNCTION that figures that out.  It won't be lightening fast, but it should work.  Something like this, I'm thinking:

DELIMITER $$

DROP FUNCTION IF EXISTS previous_trading_day$$

CREATE FUNCTION previous_trading_day (input_date DATE)
    RETURNS DATE
BEGIN
    DECLARE work_date DATE;
    SET work_date = NULL;
    
    SET work_date =
        (
         SELECT Trade_Date
         FROM full_daily_data
         WHERE Trade_Date < input_date
         ORDER BY Trade_DATE DESC
         LIMIT 1
         )
    ;

    RETURN work_date;
END $$

Open in new window


Then your update (try this out with a SELECT statement first, of course) would look something like this:

update fdd1
    set fdd1.Prior_Open = fdd2.Day_Open,
          fdd1.Prior_Close = fdd2.Day_Close
    from full_daily_data fdd1
    inner join full_daily_data fdd2
    on fdd2.Trade_Date = previous_trade_date(fdd2.Trade_Date)

Open in new window

0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 39212209
aside from the issue of aligning the correct dates, please notice that your joins require symbol in them... (it was an issue I attempted to point out in an earlier question but was too late)
update full_daily_data fdd1
inner join full_daily_data fdd2
on fdd1.symbol = fdd2.symbol
and fdd2.Trade_Date = DATE_SUB(fdd1.Trade_Date, INTERVAL 1 DAY)
set
  fdd1.Prior_Open  = fdd2.Day_Open
, fdd1.Prior_High  = fdd2.Day_High
, fdd1.Prior_Low   = fdd2.Day_Low
, fdd1.Prior_Close = fdd2.Day_Close
;

Open in new window

see: http://sqlfiddle.com/#!9/cc5f0/1
0
 
LVL 48

Accepted Solution

by:
PortletPaul earned 250 total points
ID: 39212254
Perhaps that function also need to consider symbol? (in addition to the absolute necessity for symbol in the joins), to allow for exceptions to trading cycles in certain symbols if these occur. Like this:
update full_daily_data fdd1
inner join full_daily_data fdd2
on fdd1.symbol = fdd2.symbol
and fdd2.Trade_Date = previous_trade_date(fdd2.symbol, fdd2.Trade_Date)
set
  fdd1.Prior_Open  = fdd2.Day_Open
, fdd1.Prior_High  = fdd2.Day_High
, fdd1.Prior_Low   = fdd2.Day_Low
, fdd1.Prior_Close = fdd2.Day_Close
;

Open in new window

with an extra parameter in the function proposed earlier
DELIMITER $$

DROP FUNCTION IF EXISTS previous_trading_day$$

CREATE FUNCTION previous_trading_day (input_symbol VARCHAR, input_date DATE)
    RETURNS DATE
BEGIN
    DECLARE work_date DATE;
    SET work_date = NULL;
    
    SET work_date =
        (
         SELECT Trade_Date
         FROM full_daily_data
         WHERE symbol = input_symbol 
         AND Trade_Date < input_date
         ORDER BY Trade_DATE DESC
         LIMIT 1
         )
    ;

    RETURN work_date;
END $$

Open in new window

0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 39258966
cashonly, is this question finished now?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction Hopefully the following mnemonic and, ultimately, the acronym it represents is common place to all those reading: Please Excuse My Dear Aunt Sally (PEMDAS). Briefly, though, PEMDAS is used to signify the order of operations (http://en.…
If you find yourself in this situation “I have used SELECT DISTINCT but I’m getting duplicates” then I'm sorry to say you are using the wrong SQL technique as it only does one thing which is: produces whole rows that are unique. If the results you a…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now