简体   繁体   English

SQL匹配基于2个条件的行

[英]SQL match rows based on 2 criteria

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. id是row_idsecurity_id是每个安全性的id。 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: 首先,我运行一个查询来查找每个安全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

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) . 最后我要做的是从主数据集中仅选择每个security_id那些行,其中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) . 我不知道如何构建它,因为我觉得我需要一个循环来通过security_id来子集数据,然后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? 有什么建议么?

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

You didn't say what version of SQL Server you were on, but assuming it's 2005+, you can use a common table expression: 您没有说出您所使用的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM