Re: need help with a complicated join

2004-05-26 Thread Robert A. Rosenberg
At 14:07 -0500 on 05/25/2004, <[EMAIL PROTECTED]> wrote about need 
help with a complicated join:

I am trying to come up with a query that takes two tables, one with
non-split-adjusted historical stock prices, and one with information on
splits, for instance:
CREATE TABLE quotes (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
quote   FLOAT   NOT NULL,
PRIMARY KEY (symbol, date),
INDEX (date),
);
INSERT quotes VALUES ("A", "2004-01-01", 3);
INSERT quotes VALUES ("A", "2004-01-02", 3);
INSERT quotes VALUES ("A", "2004-01-03", 3);
INSERT quotes VALUES ("A", "2004-01-04", 3);
INSERT quotes VALUES ("A", "2004-01-05", 2);
INSERT quotes VALUES ("A", "2004-01-06", 2);
INSERT quotes VALUES ("A", "2004-01-07", 2);
INSERT quotes VALUES ("A", "2004-01-08", 1);
INSERT quotes VALUES ("A", "2004-01-09", 1);
CREATE TABLE splits (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
split_from  INT UNSIGNEDNOT NULL,
split_toINT UNSIGNEDNOT NULL,
PRIMARY KEY (symbol, date),
);
INSERT splits VALUES ("A", "2004-01-05", 2, 3);
INSERT splits VALUES ("A", "2004-01-08", 1, 2);
I need to be able to pull out split-adjusted quotes, like this:
SELECT symbol, date, ...some magic... FROM quotes WHERE symbol = "A" ORDER
BY date;
+++---++
| symbol | date   | quote | adjusted_quote |
+++---++
| A  | 2004-01-01 | 3 |  1 |
| A  | 2004-01-02 | 3 |  1 |
| A  | 2004-01-03 | 3 |  1 |
| A  | 2004-01-04 | 3 |  1 |
| A  | 2004-01-05 | 2 |  1 |
| A  | 2004-01-06 | 2 |  1 |
| A  | 2004-01-07 | 2 |  1 |
| A  | 2004-01-08 | 1 |  1 |
| A  | 2004-01-09 | 1 |  1 |
+++---++
Split-adjusting means that on a split date all previous prices are
multiplied by "split_from/split_to" ratio. In my example two splits took
place, one on 2004-01-05, which multiplied all previous prices by 2/3 and
another one on 2004-01-08, which multiplied all previous prices (including
those already affected by first split) by 1/2.
Any help would be appreciated.
Question: Are you doing this direct in MySQL or is it being done as a 
Web Inquiry that is doing the MySQL Select "Under the Covers" and 
then displaying the result? If the latter, then you can do it by 
first building a Temp Table of all records where symbol="A" (fill in 
the requested symbol from the user query) AND date=as-of-date (again 
supplied by user) creating an adjusted field equal to the quote. The 
temp table now has only the requested table rows and ends at the 
as-of-date. You then read the splits table for all records dated 
before or on the as-of-date and do the updates to the adjusted field 
for each adjusted row (you can have the loop update the factor as 
needed so you only need to run the table once). Then just read and 
display the temp table.

One additional question. From your definition when you say 
"non-split-adjusted historical stock prices" I assume that you mean 
that on the day a split occurs, that day's quote HAS BEEN adjusted 
for the split and all subsequent quotes are based on the status of 
the latest split. What you are trying to do with the adjusted column 
is adjust for the splits and have the quotes reflect the quote in 
terms of a block of stock quoted on day one in the table. IOW: If the 
first quote in the table was for 1 share and due to splits that block 
is now 5 shares, you want to multiple the todays (1-share) quote by 5 
to get a constant based price and do the same on the other day by 
using the then current block size as the adjustment factor.

--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]


RE: need help with a complicated join

2004-05-26 Thread mysql
Wow! What a trick! Harold, I am ashamed for not remembering that log/exp
technique myself.

Just out of curiosity, what is the difference between these two:

COALESCE(*expression*, 1)
IFNULL(*expression*, 1)

Right off the bat, I know that COALESCE accepts multiple arguments, while
IFNULL always takes two. If I only have two arguments, is there any
advantage in using one or the other from any optimization points of view?

---
Fyodor Golos
Stockworm, Inc.
 

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, May 26, 2004 8:42 AM
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]; news
Subject: Re: need help with a complicated join


Harold, you win the "EUREKA" prize of the month!

I had forgotten all about that silly algebraic trick. This answers another
person's post from last week. (I will try to find it again) also looking
for a PRODUCT() function.

I agree about the unknown performance. If you only need to return adjusted
quotes for particular symbols and a date range, you *may* be better off
pre-calcuating the LOG()s in a temp table for what you need to quote. You
can combine that with the stock symbols and the date ranges (from your main
query) to minimize the number of items that the LEFT JOIN ends up
processing.

something like :

   CREATE TEMPORARY TABLE tmpSplits
   SELECT Symbol, date, log(split_from/split_to) as logadj
   FROM splits
   WHERE date > *earliest date* AND Symbol in (*list of symbols*)

   SELECT q.symbol, q.date, q.quote,
  q.quote * COALESCE(exp(sum(ts.logadj)), 1)
   FROM quotes q
   LEFT JOIN tmpSplits ts ON ts.symbol = q.symbol AND ts.date > q.date
   WHERE q.symbol in (*list of symbols*) and q.date > *earliest date*
   GROUP BY q.symbol, q.date, q.quote
   ORDER BY q.symbol, q.date

only benchmarking will truly show which is faster.

Once again - A HUGE "way-to-go" for the math lesson!

Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine



 

  Harald Fuchs

  <[EMAIL PROTECTED]To:
[EMAIL PROTECTED]   
  .net>cc:

  Sent by: newsFax to:

  <[EMAIL PROTECTED]    Subject:  Re: need help with
a complicated join   
  rg>

 

 

  05/26/2004 06:00

  AM

  Please respond to

  hf517

 

 





In article <[EMAIL PROTECTED]>,
Harald Fuchs <[EMAIL PROTECTED]> writes:

>   SELECT q.symbol, q.date,
>  q.quote * product (s.split_from / s.split_to) AS adjusted_quote
>   FROM quotes q
>   LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
>   GROUP BY q.symbol, q.date, q.quote
>   ORDER BY q.symbol, q.date

> The problem is how to define the 'product' aggregate (along the lines
> of 'sum').

[ I like talking to myself :-) ]

A workaround for the missing product aggregate would be

  SELECT q.symbol, q.date, q.quote,
 q.quote * exp(sum(log(coalesce(s.split_from/s.split_to,1
  FROM quotes q
  LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
  GROUP BY q.symbol, q.date, q.quote
  ORDER BY q.symbol, q.date

but don't ask me how that performs...


--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]







-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: need help with a complicated join

2004-05-26 Thread SGreen

Harold, you win the "EUREKA" prize of the month!

I had forgotten all about that silly algebraic trick. This answers another
person's post from last week. (I will try to find it again) also looking
for a PRODUCT() function.

I agree about the unknown performance. If you only need to return adjusted
quotes for particular symbols and a date range, you *may* be better off
pre-calcuating the LOG()s in a temp table for what you need to quote. You
can combine that with the stock symbols and the date ranges (from your main
query) to minimize the number of items that the LEFT JOIN ends up
processing.

something like :

   CREATE TEMPORARY TABLE tmpSplits
   SELECT Symbol, date, log(split_from/split_to) as logadj
   FROM splits
   WHERE date > *earliest date* AND Symbol in (*list of symbols*)

   SELECT q.symbol, q.date, q.quote,
  q.quote * COALESCE(exp(sum(ts.logadj)), 1)
   FROM quotes q
   LEFT JOIN tmpSplits ts ON ts.symbol = q.symbol AND ts.date > q.date
   WHERE q.symbol in (*list of symbols*) and q.date > *earliest date*
   GROUP BY q.symbol, q.date, q.quote
   ORDER BY q.symbol, q.date

only benchmarking will truly show which is faster.

Once again - A HUGE "way-to-go" for the math lesson!

Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine



   
  
  Harald Fuchs 
  
  <[EMAIL PROTECTED]To:   [EMAIL PROTECTED]
   
  .net>cc: 
  
  Sent by: newsFax to: 
  
  <[EMAIL PROTECTED]Subject:  Re: need help with a 
complicated join   
  rg>  
  
   
  
   
  
  05/26/2004 06:00 
  
  AM   
  
  Please respond to
  
  hf517
  
   
  
   
  




In article <[EMAIL PROTECTED]>,
Harald Fuchs <[EMAIL PROTECTED]> writes:

>   SELECT q.symbol, q.date,
>  q.quote * product (s.split_from / s.split_to) AS adjusted_quote
>   FROM quotes q
>   LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
>   GROUP BY q.symbol, q.date, q.quote
>   ORDER BY q.symbol, q.date

> The problem is how to define the 'product' aggregate (along the lines
> of 'sum').

[ I like talking to myself :-) ]

A workaround for the missing product aggregate would be

  SELECT q.symbol, q.date, q.quote,
 q.quote * exp(sum(log(coalesce(s.split_from/s.split_to,1
  FROM quotes q
  LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
  GROUP BY q.symbol, q.date, q.quote
  ORDER BY q.symbol, q.date

but don't ask me how that performs...


--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]







-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



RE: need help with a complicated join

2004-05-26 Thread electroteque
man i didnt even know you can do this

AND s.date > q.date

i assumed that goes in a where clause ?

> -Original Message-
> From: news [mailto:[EMAIL PROTECTED] Behalf Of Harald Fuchs
> Sent: Wednesday, May 26, 2004 8:01 PM
> To: [EMAIL PROTECTED]
> Subject: Re: need help with a complicated join
>
>
> In article <[EMAIL PROTECTED]>,
> Harald Fuchs <[EMAIL PROTECTED]> writes:
>
> >   SELECT q.symbol, q.date,
> >  q.quote * product (s.split_from / s.split_to) AS adjusted_quote
> >   FROM quotes q
> >   LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
> >   GROUP BY q.symbol, q.date, q.quote
> >   ORDER BY q.symbol, q.date
>
> > The problem is how to define the 'product' aggregate (along the lines
> > of 'sum').
>
> [ I like talking to myself :-) ]
>
> A workaround for the missing product aggregate would be
>
>   SELECT q.symbol, q.date, q.quote,
>  q.quote * exp(sum(log(coalesce(s.split_from/s.split_to,1
>   FROM quotes q
>   LEFT JOIN splits s ON s.symbol = q.symbol AND s.date > q.date
>   GROUP BY q.symbol, q.date, q.quote
>   ORDER BY q.symbol, q.date
>
> but don't ask me how that performs...
>
>
> --
> MySQL General Mailing List
> For list archives: http://lists.mysql.com/mysql
> To unsubscribe:
http://lists.mysql.com/[EMAIL PROTECTED]


-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: need help with a complicated join

2004-05-25 Thread SGreen

You are beyond the realm of SQL. What you would need for something like
this is a dynamically-generated case statement that would apply different
multipliers based on the date of the quote you are trying to adjust. For
those quote values that exist BEFORE multiple splits you must adjust by the
PRODUCT of those splits to achieve your adjusted split.

There is currently no PRODUCT() keyword that is analogous to the SUM()
keyword or you would be able to get your historical multipliers through
sub-selects.

It may be possible to write a UDF that takes the stock symbol and a target
date and computes the adjustment ratio for that date (but I haven't built
one yet so I don't know for sure)

Yours,
Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine


   
  
  <[EMAIL PROTECTED]   
   
  com> To:   <[EMAIL PROTECTED]>   
  
  Sent by: "Fyodor cc: 
  
  Golos"   Fax to: 
  
  <[EMAIL PROTECTED]Subject:  need help with a complicated 
join   
  com> 
  
   
  
   
  
  05/25/2004 03:07 
  
  PM   
  
   
  
   
  




I am trying to come up with a query that takes two tables, one with
non-split-adjusted historical stock prices, and one with information on
splits, for instance:

CREATE TABLE quotes (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
quote   FLOAT   NOT NULL,
PRIMARY KEY (symbol, date),
INDEX (date),
);
INSERT quotes VALUES ("A", "2004-01-01", 3);
INSERT quotes VALUES ("A", "2004-01-02", 3);
INSERT quotes VALUES ("A", "2004-01-03", 3);
INSERT quotes VALUES ("A", "2004-01-04", 3);
INSERT quotes VALUES ("A", "2004-01-05", 2);
INSERT quotes VALUES ("A", "2004-01-06", 2);
INSERT quotes VALUES ("A", "2004-01-07", 2);
INSERT quotes VALUES ("A", "2004-01-08", 1);
INSERT quotes VALUES ("A", "2004-01-09", 1);

CREATE TABLE splits (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
split_from  INT UNSIGNEDNOT NULL,
split_toINT UNSIGNEDNOT NULL,
PRIMARY KEY (symbol, date),
);
INSERT splits VALUES ("A", "2004-01-05", 2, 3);
INSERT splits VALUES ("A", "2004-01-08", 1, 2);

I need to be able to pull out split-adjusted quotes, like this:

SELECT symbol, date, ...some magic... FROM quotes WHERE symbol = "A" ORDER
BY date;

+++---++
| symbol | date   | quote | adjusted_quote |
+++---++
| A  | 2004-01-01 | 3 |  1 |
| A  | 2004-01-02 | 3 |  1 |
| A  | 2004-01-03 | 3 |  1 |
| A  | 2004-01-04 | 3 |  1 |
| A  | 2004-01-05 | 2 |  1 |
| A  | 2004-01-06 | 2 |  1 |
| A  | 2004-01-07 | 2 |  1 |
| A  | 2004-01-08 | 1 |  1 |
| A  | 2004-01-09 | 1 |  1 |
+++---++

Split-adjusting means that on a split date all previous prices are
multiplied by "split_from/split_to" ratio. In my example two splits took
place, one on 2004-01-05, which multiplied all previous prices by 2/3 and
another one on 2004-01-08, which multiplied all previous prices (including
those already affected by first split)

need help with a complicated join

2004-05-25 Thread mysql
I am trying to come up with a query that takes two tables, one with
non-split-adjusted historical stock prices, and one with information on
splits, for instance:

CREATE TABLE quotes (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
quote   FLOAT   NOT NULL,
PRIMARY KEY (symbol, date),
INDEX (date),
);
INSERT quotes VALUES ("A", "2004-01-01", 3);
INSERT quotes VALUES ("A", "2004-01-02", 3);
INSERT quotes VALUES ("A", "2004-01-03", 3);
INSERT quotes VALUES ("A", "2004-01-04", 3);
INSERT quotes VALUES ("A", "2004-01-05", 2);
INSERT quotes VALUES ("A", "2004-01-06", 2);
INSERT quotes VALUES ("A", "2004-01-07", 2);
INSERT quotes VALUES ("A", "2004-01-08", 1);
INSERT quotes VALUES ("A", "2004-01-09", 1);

CREATE TABLE splits (
symbol  VARCHAR(127)NOT NULL,
dateDATENOT NULL,
split_from  INT UNSIGNEDNOT NULL,
split_toINT UNSIGNEDNOT NULL,
PRIMARY KEY (symbol, date),
);
INSERT splits VALUES ("A", "2004-01-05", 2, 3);
INSERT splits VALUES ("A", "2004-01-08", 1, 2);

I need to be able to pull out split-adjusted quotes, like this:

SELECT symbol, date, ...some magic... FROM quotes WHERE symbol = "A" ORDER
BY date;

+++---++
| symbol | date   | quote | adjusted_quote |
+++---++
| A  | 2004-01-01 | 3 |  1 |
| A  | 2004-01-02 | 3 |  1 |
| A  | 2004-01-03 | 3 |  1 |
| A  | 2004-01-04 | 3 |  1 |
| A  | 2004-01-05 | 2 |  1 |
| A  | 2004-01-06 | 2 |  1 |
| A  | 2004-01-07 | 2 |  1 |
| A  | 2004-01-08 | 1 |  1 |
| A  | 2004-01-09 | 1 |  1 |
+++---++

Split-adjusting means that on a split date all previous prices are
multiplied by "split_from/split_to" ratio. In my example two splits took
place, one on 2004-01-05, which multiplied all previous prices by 2/3 and
another one on 2004-01-08, which multiplied all previous prices (including
those already affected by first split) by 1/2.

Any help would be appreciated.

---
Fyodor Golos
Stockworm, Inc.
 




--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]