如何根据条件从同一个table中selectMySQL中的数据并避免重复?
How to select data in MySQL from the same table based on conditions and avoid duplicates?
我已经阅读了相关答案,但没有找到解决问题的办法。请帮助我解决以下问题:我有两个 table,我想根据男高音来匹配它们,但考虑到在一个 table 中我可以有不同的条目满足这个条件。在我想从中提取信息 (inst) 的 table 中,我有几个关于利率的数据,所有数据都在不同的行上构建,例如我可以拥有 LIBOR 或 OIS 数据。
我想执行以下查询:将第二个 table (stgy) 的男高音与第一个 table (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" table 中查询特定的基础货币和列表中的 "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" table 相同期限、货币和交易日期的汇率。现在,要获得最后的价格,它是基于证券类型的。
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
因为您没有显示 table 结构,也没有示例数据(您可以编辑原始问题以提供此类 SAMPLE 数据。
此外,您提到了防止重复...所谓重复,您是指给定货币、trade_date、期限、证券类型的多个条目(也不确定您的 table "security_type" 字段实际上与).
我通过对 inst table 进行两次左连接进行了修改。请分别确认所需条件。看起来您的 "OIS" 条件也需要加入 "tenor" 字段,但不是 "LIBOR" 值。但请注意,左连接分别明确地在 "OIS" 或 "LIBOR" 上,因此给定的 OIS/TENOR 不应有多个条目,也不应为给定的 date/currency 在 LIBOR 上重复.
然后,通过 COALESCE() 提取价格。如果第一个值为 NULL,则从第二列获取值。如果那也是空的,那么您的最后一列答案将为空,这正是您想要得到的。
我已经阅读了相关答案,但没有找到解决问题的办法。请帮助我解决以下问题:我有两个 table,我想根据男高音来匹配它们,但考虑到在一个 table 中我可以有不同的条目满足这个条件。在我想从中提取信息 (inst) 的 table 中,我有几个关于利率的数据,所有数据都在不同的行上构建,例如我可以拥有 LIBOR 或 OIS 数据。 我想执行以下查询:将第二个 table (stgy) 的男高音与第一个 table (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" table 中查询特定的基础货币和列表中的 "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" table 相同期限、货币和交易日期的汇率。现在,要获得最后的价格,它是基于证券类型的。
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
因为您没有显示 table 结构,也没有示例数据(您可以编辑原始问题以提供此类 SAMPLE 数据。
此外,您提到了防止重复...所谓重复,您是指给定货币、trade_date、期限、证券类型的多个条目(也不确定您的 table "security_type" 字段实际上与).
我通过对 inst table 进行两次左连接进行了修改。请分别确认所需条件。看起来您的 "OIS" 条件也需要加入 "tenor" 字段,但不是 "LIBOR" 值。但请注意,左连接分别明确地在 "OIS" 或 "LIBOR" 上,因此给定的 OIS/TENOR 不应有多个条目,也不应为给定的 date/currency 在 LIBOR 上重复.
然后,通过 COALESCE() 提取价格。如果第一个值为 NULL,则从第二列获取值。如果那也是空的,那么您的最后一列答案将为空,这正是您想要得到的。