Reputation: 28159
I have a dataset of securities prices in a database. The data is structured like this:
id security_id time_to_maturity price
001 01 1.5 100.45
002 01 1.3 101.45
003 01 1.1 102.45
004 01 1.02 101.45
005 01 1.0 101.45
006 03 22.3 94.45
007 03 22.1 96.45
008 03 21.8 98.45
009 05 4.2 111.45
010 05 4.1 112.45
011 05 3.8 111.45
...
id is the row_id
and security_id
is the id of each security. I am trying to get only data from a certain time range for each security. First I run a query to find the min and max for each security id, then find the difference between the min and max and finally find a value that is 10% more than the minimum like this:
SELECT security_id, MIN(time_to_maturity), MAX(time_to_maturity),
MAX(time_to_maturity) - MIN(time_to_maturity) tDiff,
((MAX(time_to_maturity) - MIN(time_to_maturity)) * .1) + MIN(time_to_maturity)
FROM db1
group by security_id
order by security_id
This gives me the following:
security_id min() max() diff min+(diff*.1)
01 1.0 1.5 .5 1.05
03 21.8 22.3 .5 21.85
05 3.8 4.2 .4 3.84
Finally what I'd like to do is select from the main data set only those rows for each security_id
where the time_to_maturity is < min+(diff*.1)
.
I'm not sure how to structure it though as I feel like I need a loop to subset data by security_id, then by time_to_maturity is < min+(diff*.1)
.
The answer would look something like this:
id security_id time_to_maturity price
004 01 1.02 101.45
005 01 1.0 101.45
008 03 21.8 98.45
011 05 3.8 111.45
Any suggestions?
Upvotes: 0
Views: 113
Reputation: 32697
You didn't say what version of SQL Server you were on, but assuming it's 2005+, you can use a common table expression:
with cte as (
SELECT security_id,
((MAX(time_to_maturity) - MIN(time_to_maturity)) * .1) + MIN(time_to_maturity) as threshold
FROM db1
group by security_id
)
select id, db1.security_id, time_to_maturity, price
from db1
inner join cte
on db1.security_id = cte.security_id
where time_to_maturity < threshold
Upvotes: 1
Reputation: 13534
SELECT A.id,B.security_id,A.time_to_maturity,A.price
FROM db1 A,
(
SELECT security_id, MIN(time_to_maturity) AS min_time_to_maturity, MAX(time_to_maturity) AS max_time_to_maturity,
MAX(time_to_maturity) - MIN(time_to_maturity) tDiff,
((MAX(time_to_maturity) - MIN(time_to_maturity)) * .1) + MIN(time_to_maturity)
FROM db1
group by security_id
order by security_id
) B
WHERE A.security_id = B.security_id
AND A.time_to_maturity < (B.min_time_to_maturity+(B.tdiff*0.1));
PS:This will work only in MYSQL.
Upvotes: 1