MYSQL查询双JOIN

时间:2014-04-22 16:17:35

标签: php mysql sql inner-join semi-join

这是我的疑问:

SELECT count(*) AS COUNT
FROM `psttodo-in` p
INNER JOIN `deelgebied` d 
    ON d.`Segmentcode` = p.`Segment No_ PST`
    AND d.`Deelgebied` = p.`Deelgebied`
INNER JOIN m2m 
    ON m2m.`deelgebied` = d.`deelgebiedID`
WHERE 
    p.`Segment No_ PST` = 'PSS1400146'
    AND p.`Deelgebied` = 2
ORDER BY `afgewerkt tablet datum`

现在,当我在Sequal Pro中查看我的表格psttodo-in时,我选择了Segment No_ PST = PSS1400146Deelgebied = 2的行,我算84。但是当我运行查询时,我得到252的结果。我做错了什么?

更新

我的表结构:

table psttodo-in:
    PK No_
    Hostess Code
    Segment No_
    FK Deelgebied
    ....

table deelgebied
    Segmentcode
    Deelgebied
    map
    DeelgebiedID
    pst-active

table m2m
    PK m2mID
    FK deelgebied
    FK psthostess

1 个答案:

答案 0 :(得分:1)

由于外键引用,d中的每一行p中总是只有一行。

m2m中的每一行或d中可能有多行。事实上,由于252是84 * 3,我猜每个m2m d中有三行(或者至少平均为3)。因此,在联接的结果集中,行被加倍,来自m2m的行不同,但pd的行会重复。

有几种方法可以解决这个问题:

仅对每个p计数一次

我们知道,在重复的行中,重复pd的值。因此,选择一个已知在pd中唯一的列,并仅计算其中的不同值。我们无法选择d,因为如果两个不同的p条目引用相同的d,则可以合法地选择那些p。因此,请选择SELECT COUNT(DISTINCT p.NO_) AS COUNT FROM `psttodo-in` p INNER JOIN `deelgebied` d ON d.`Segmentcode` = p.`Segment No_ PST` AND d.`Deelgebied` = p.`Deelgebied` INNER JOIN m2m ON m2m.`deelgebied` = d.`deelgebiedID` WHERE p.`Segment No_ PST` = 'PSS1400146' AND p.`Deelgebied` = 2 ORDER BY `afgewerkt tablet datum` 的主键:

SELECT COUNT(*) AS COUNT
FROM `psttodo-in` p
INNER JOIN `deelgebied` d 
    ON d.`Segmentcode` = p.`Segment No_ PST`
    AND d.`Deelgebied` = p.`Deelgebied`
WHERE 
    p.`Segment No_ PST` = 'PSS1400146'
    AND p.`Deelgebied` = 2
    AND EXISTS (SELECT * FROM m2m WHERE m2m.`deelgebied` = d.`deelgebiedID`)
ORDER BY `afgewerkt tablet datum`

使用半连接

即使有多个匹配项,semi-join也只返回结果的一行。在SQL中编写半连接的方法如下:

{{1}}

MySQL 5.6中的半连接优化得到了改进,因此如果您使用此解决方案,我建议您进行升级。