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


因为您既不显示表结构,也不显示示例数据(您可以编辑原始问题以提供此类SAMPLE数据。

另外,您提到了防止重复...重复是指给定货币,trade_date,期限,安全类型的多个条目(还不确定“ security_type”字段实际上与哪个表相关联)。

我通过对inst表做两个左联接来进行修改。请分别确认所需条件。看起来您的“ OIS”条件也需要在“ tenor”字段上进行联接,但对于“ LIBOR”值则不需要。但是请注意,左联接分别明确地在“ OIS”或“ LIBOR”上,因此对于给定的OIS / TENOR,不应有多个条目,在给定的日期/货币上,LIBOR上不应重复。

然后,通过COALESCE()拉动价格。如果第一个值为NULL,则从第二列获取该值。如果那也为空,则您最终的答案将为空,这就是您想要获得的。

关于mysql - 如何根据条件从同一张表中选择MySQL中的数据并避免重复?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33611338/

10-11 02:48
查看更多