【问题标题】:overcoming "at least once" condition in a LEFT JOIN在 LEFT JOIN 中克服“至少一次”条件
【发布时间】:2010-11-12 12:16:28
【问题描述】:

我有以下两个表quote(date,market,ticker,close)scenario(date1,date2,period,market,ticker,ratio)。我已经编写了以下 LEFT JOIN 查询,除了一个问题之外,它可以满足我的需求:

SELECT  S.date1 AS date1, 
        S.date2 AS date2,
        S.period AS period,
        Q.market AS market,
        Q.ticker AS ticker,
        Q.close * EXP(S.ratio) AS scenario

FROM portfolio.quote Q  LEFT JOIN  portfolio.scenario S 

      ON Q.market = S.market AND
         Q.ticker = S.ticker AND
         S.date1 >= '2010-06-01' AND
         S.date2 <= '2010-07-01' AND
         S.period = 'WEEK'

WHERE Q.date = '2010-07-01' 
ORDER BY S.date1, S.date2, S.period, Q.market, Q.ticker

前面的查询返回结果,只要报价表中的 (market,ticker) 与方案表中的等价 (market,ticker) 不匹配,就会为属于方案表的列添加 NULL 值的行像这样:

date1, date2, period, market , ticker, scenario
NULL , NULL , NULL  , 'sp500', 'QEP' , NULL

在“2010-06-01”和“2010-07-01”之间的“WEEK”期间,('sp500','QEP') 可能有许多不匹配的行,但只有一行表示这个在属于场景表的列中具有 NULL 值的事实。更不用说,在这些结果中,(market,ticker) 有许多不匹配的行,但至少存在一个匹配,因此查询不会为这些行返回 NULL 值。

我想要做的是,例如,如果 Q.date = '2010-07-01' 返回 500 行的报价表,那么将有 500 * (DISTINCT date1,date,period)。仅当以下条件不匹配时,场景列中的值为 NULL:

Q.market = S.market AND
Q.ticker = S.ticker

例如,NULL 结果看起来像这样:

date1        , date2        , period  , market , ticker, scenario
'2010-06-01' , '2010-06-08' , 'WEEK'  , 'sp500', 'QEP' , NULL
'2010-06-08' , '2010-06-15' , 'WEEK'  , 'sp500', 'QEP' , NULL
'2010-06-15' , '2010-06-23' , 'WEEK'  , 'sp500', 'A'   , NULL

另一个例子,例如 (market,ticker,close) 与报价表中的 Q.date = '2010-07-01' 匹配的行是:

('sp','A',1)
('sp','AA',2)

以及符合条件的(date1,date2,period,market,ticker,ratio)

     S.date1 >= '2010-06-01' AND
     S.date2 <= '2010-07-01' AND
     S.period = 'WEEK'

是:

('2010-06-01','2010-06-08','WEEK','sp','A',0.43)
('2010-06-01','2010-06-08','WEEK','sp','AA',0.21)

('2010-06-08','2010-06-20','WEEK','sp','A',0.49)

('2010-06-20','2010-06-27','WEEK','sp','A',0.46)
('2010-06-20','2010-06-27','WEEK','sp','B',0.23)

那么我的查询结果应该返回

('2010-06-01','2010-06-08','WEEK','sp','A',1*EXP(0.43))
('2010-06-01','2010-06-08','WEEK','sp','AA',2*EXP(0.21))

('2010-06-08','2010-06-20','WEEK','sp','A',1*EXP(0.49))
('2010-06-08','2010-06-20','WEEK','sp','AA',NULL)

('2010-06-20','2010-06-27','WEEK','sp','A',1*EXP(0.46))
('2010-06-20','2010-06-27','WEEK','sp','AA',NULL)

这种事情在 MySQL 中可能吗?非常感谢任何帮助:)

【问题讨论】:

    标签: mysql join query-optimization left-join


    【解决方案1】:

    由于您使用的是 LEFT 连接,因此即使在 ON 条件与其他表(场景)不完全匹配时,也会显示 FROM 表的(引号)行。其他表中的列被简单地替换为 NULL。

    但是,您一直想做的是显示场景表中的所有行,而不是报价表中的所有行。因此,我建议您使用 RIGHT join 或将查询部分替换为
    FROM portfolio.scenario S LEFT JOIN portfolio.quote Q

    希望能解决您的问题。

    【讨论】:

    • Thanx 对您的反馈感到好奇,但实际上我不想显示场景表中的所有行而不是报价表。我将用一个例子重新编辑我的问题来说明我的观点。
    猜你喜欢
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 2012-08-22
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多