mysql - MySQL中如何根据条件从同一张表中选取数据并避免重复?

标签 mysql if-statement select case

我已阅读相关答案,但没有找到解决我的问题的方法。请帮助我解决以下问题:我有两个表,我想根据期限来匹配它们,但考虑到在一个表中我可以有满足此条件的不同条目。在我想从中提取信息的表(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/

相关文章:

mysql - 'where clause' Rails 4 中的未知列

Mysql函数更新外键

Java继承(if中的局部变量/boolean 值)

c# - 如果(<对象> == <整数>)

mysql - mysql查询得到重复的结果

javascript - ng-options 从字典传递值

mysql - 如何将两个单独的文本连接到一个 - 从字符串中选择 - IN MySQL

python - 带 pass 语句的条件

php - 选择所有帖子的所有评论 php mysql

mysql - 从数据库的所有mysql表名中删除前缀