MySQL左连接返回错误的结果数

时间:2012-11-25 00:17:47

标签: mysql left-join

希望有人可以帮我解决这个问题。我有一张包含以下数据的表格:

site_id  type                           key               data
2        organic-keywords-last-month    (not provided)    9064
2        organic-keywords-last-month    bmi               345
2        organic-keywords-last-month    bmi kalkulator    445
2        organic-keywords-last-month    grove pannekaker  678
2        organic-keywords-last-month    grove vafler      976
2        organic-keywords-last-month    lapper            475
2        organic-keywords-last-month    melk.no           624
2        organic-keywords-last-month    ostesuffle        361
2        organic-keywords-last-month    scones            697
2        organic-keywords-last-month    sunne pannekaker  658
2        organic-keywords-last-month    sunne vafler      484
2        organic-keywords-this-month    (not provided)    10034
2        organic-keywords-this-month    bmi kalkulator    659
2        organic-keywords-this-month    grove pannekaker  721
2        organic-keywords-this-month    grove vafler      857
2        organic-keywords-this-month    lapper            515
2        organic-keywords-this-month    melk.no           587
2        organic-keywords-this-month    ostesuffle        433
2        organic-keywords-this-month    scones            626
2        organic-keywords-this-month    smultringer       401
2        organic-keywords-this-month    sunne pannekaker  566
2        organic-keywords-this-month    sunne vafler      407

我想要做的是查询所有有机关键字 - 本月,然后将它们加入到有机关键字 - 上个月,这样我就可以得到本月11个关键字的列表,表现,以及他们上个月的表现。

我使用以下查询:

SELECT 
    ktm.key AS keyword, 
    ktm.data AS `this month`, 
    klm.data AS `last month` 
FROM
    data AS ktm 
    LEFT JOIN data AS klm ON 
        (ktm.key = klm.key AND ktm.type = 'organic-keywords-this-month' 
        AND klm.type = 'organic-keywords-last-month') 
WHERE 
    ktm.site_id = 2 
    AND klm.site_id = 2 
ORDER BY 
    `this month` ASC

我认为应该返回11行,因为有11行类型'有机关键字 - 本月',但是当我运行它时它只返回10行,看起来更像是内部加入表而不是比离开加入。

有人有什么想法吗?

4 个答案:

答案 0 :(得分:2)

我认为查询非常接近......但是你的连接条件也是相同的类型,并且只将类型的QUALIFIER放在与这个月数据相关的WHERE子句中

SELECT 
      ktm.key AS keyword, 
      ktm.data AS this_month, 
      klm.data AS last_month 
   FROM 
      data AS ktm 
         LEFT JOIN data AS klm 
             ON klm.site_id = ktm.site_id
            AND klm.key = ktm.key 
            AND klm.type = 'organic-keywords-last-month'
   WHERE 
          ktm.site_id = 2 
      AND ktm.type = 'organic-keywords-this-month' 
   ORDER BY 
     this_month ASC 

通过应用" AND ktm.type ='有机......',这将恰当符合您现在想要的内容。

然而,LEFT JOIN也将基于" AND ktm.type = klm.type"显式匹配。条款。请注意,我调整为类似地应用您的相同网站ID"就像上个月一样。

我会确保数据表上有一个索引(site_id,type,key)

答案 1 :(得分:1)

您的WHERE需要klm中的特定值,因此查询不会返回甚至没有任何klm值的第11行。

取出WHERE的klm一半并将其放入LEFT JOIN。

答案 2 :(得分:1)

像保罗格雷戈里说的那样。我认为应该接受这个答案。我只想补充说,网站值应该在join'on'子句中进行比较,当且仅当你想要将键值的比较限制为来自同一站点的键值时,这似乎是你想要的。在任何一种情况下,如果你想将结果限制为ktm.site = 2,那么可以在join on子句,ktm.site = klm.site或where子句中使用它,只是不要放klm .site在where子句中。

答案 3 :(得分:0)

如果您将表分成两个表,一个用于本月,一个用于最后一个月,您会注意到键列中存在轻微差异。上个月的小组有一个名为'bmi'的密钥,这个月缺少,本月有一个名为'smultringer'的密钥,这个密钥在上个月丢失了。由于缺少您在klm.key = ktm.key中指定的匹配项,因此这些行将被排除在联接之外,只有10行而不是11行。

编辑:我不是说要实际分开桌子,我打算在精神上这样做以比较各组。