2012-03-31 120 views
0

我有一个数据库中证券价格的数据集。该数据的结构是这样的:基于2条件的SQL匹配行

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是row_idsecurity_id是每个安全的ID。我试图从每个安全性的特定时间范围获取数据。首先,我运行一个查询查找每个安全ID的最小值和最大值,然后找到最小和最大和最后的区别找到一个值,该值大于最小像这样10%以上的是:

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 

这使我下面的:

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 

最后,我想要做的是从主数据集只有那些行每个security_idtime_to_maturity is < min+(diff*.1)选择。

我不知道如何构造它,因为我觉得我需要一个循环来通过security_id子集数据,然后通过time_to_maturity is < min+(diff*.1)

答案会是这个样子:

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 

有什么建议?

+0

是您的关于MySQL的问题,或有关SQL Server?他们不是一回事。 – 2012-03-31 03:24:12

回答

1
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:这只适用于MYSQL。

1

你没有说你是什么版本的SQL Server上,但假设它是2005+,你可以使用一个公用表表达式:

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 
+1

另外,我会注意到,你可以在你的表达式上做一个小的代数来简化它。我把这个作为练习留给读者。 ;) – 2012-03-31 04:59:04