我已阅读相关答案,但没有找到解决我的问题的方法。请帮助我解决以下问题:我有两个表,我想根据期限来匹配它们,但考虑到在一个表中我可以有满足此条件的不同条目。在我想从中提取信息的表(inst)中,我有几个有关利率的数据,所有数据都在不同的行上构建,例如我可以获得 LIBOR 或 OIS 数据。 我想做以下查询:将第二个表 (stgy) 中的期限与第一个表 (inst) 中可用的 OIS 数据进行匹配,否则获取 LIBOR 数据。 下面是我尝试过但不起作用的代码:
SELECT CASE
WHEN stgy.tenor IN ('1D','1W','2W','3W','1M','2M','3M','4M','5M','6M','7M','8M','9M','10M','11M')
THEN ( CASE WHEN security_type='OIS' THEN
(SELECT price_last FROM inst WHERE currency = @base_crncy AND trade_date = @date_of_interest AND tenor = stgy.tenor)
ELSE
(SELECT price_last
FROM inst
WHERE security_type IN ('LIBOR') AND currency = @base_crncy AND trade_date = @date_of_interest
)
END AS rate
)
ELSE NULL
END AS int_rate
我也在同一交易日和同一货币进行匹配。请考虑我也可以有其他 security_type 。感谢您的帮助!
更新的查询:
SELECT CASE WHEN stgy.tenor IN('1D','1W','2W','3W','1M','2M','3M','4M','5M','6M','7M','8M','9M','10M','11M')
THEN (COALESCE((SELECT price_last FROM instruments WHERE security_type='OIS' AND currency=@base_crncy AND trade_date = @date_of_interest AND tenor=stgy.tenor),
(SELECT price_last FROM instruments WHERE security_type='LIBOR' AND currency = @base_crncy AND trade_date = @date_of_interest AND tenor=stgy.tenor))
)
ELSE NULL
END AS int_rate
-- and here i add from where based on the join between the tables (this part works)
最佳答案
首先,为了简化,您似乎只想从“stgy”表中查询特定的基础货币和列表中的“tenor”值。
SELECT
s.tenor
FROM
stgy s
WHERE
s.currency = @base_crncy
AND s.tenor IN ('1D', '1W', '2W', '3W', '1M', '2M', '3M', '4M',
'5M', '6M', '7M', '8M', '9M', '10M', '11M')
由此,您需要“inst”表中相同期限、货币和交易日期的汇率。现在,要获取最后的价格,它是基于安全类型的。
SELECT
s.tenor,
COALESCE( i.price_last, i2.price_last ) as Price_Last
FROM
stgy s
LEFT JOIN inst i
ON s.currency = i.currency
AND s.tenor = i.tenor
AND i.trade_date = @date_of_interest
AND i.securityType = 'OIS'
LEFT JOIN inst i2
ON s.currency = i2.currency
AND i2.trade_date = @date_of_interest
AND i2.securityType = 'LIBOR'
WHERE
s.currency = @base_crncy
AND s.tenor IN ('1D', '1W', '2W', '3W', '1M', '2M', '3M', '4M',
'5M', '6M', '7M', '8M', '9M', '10M', '11M')
为了帮助优化查询,我将在
上添加索引stgy ( currency, tenor )
inst ( currency, trade_date, tenor, security_type )
创建索引的语法...
ALTER TABLE `stgy` ADD INDEX `currency_tenor` (`currency`, `tenor` );
ALTER TABLE `inst` ADD INDEX `cur_trade_ten_sec` (`currency`, `trade_date, `tenor`, `security_type` );
现在,您可能需要调整以下条件:
AND case when s.securityType = 'OIS'
then s.tenor = i.tenor
else s.security_type IN ('LIBOR') end
因为您没有显示表结构,也没有显示示例数据(您可以编辑原始问题以提供此类示例数据。
此外,您提到防止重复...您所说的重复是指给定货币、交易日期、期限、证券类型的多个条目(也不确定您的“security_type”字段实际与哪个表关联)。
我通过对 inst 表进行两次左连接进行修改。请分别确认所需的标准。看起来您的“OIS”标准也需要加入“tenor”字段,但不需要加入“LIBOR”值。但请注意,左连接分别在“OIS”或“LIBOR”上明确显示,因此给定的 OIS/TENOR 不应有多个条目,每个给定日期/货币的 LIBOR 也不应有重复条目。
然后,通过 COALESCE() 拉取价格。如果第一个值为 NULL,则从第二列获取值。如果它也为空,那么您的最终列答案将为空,这就是您想要得到的。
关于mysql - MySQL中如何根据条件从同一张表中选取数据并避免重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33611338/