1

这是我的查询:

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`

psttodo-in现在,当我在 Sequal Pro 中检查我的表时,我选择了 whereSegment No_ PST = PSS1400146Deelgebied = 2我 count的行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
4

1 回答 1

1

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

m2m但是对于 each 或 in 中可能有多行d。事实上,由于 252 是 84 * 3,我猜m2m每个有三行d(或者至少平均值是三行)。因此,在连接的结果集中,行增加了三倍,其中不同的行来自m2m但来自p和的行d被重复。

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

每个p只计算一次

我们知道,在重复的行中,来自p和的值d是重复的。因此,选择一个已知在por中唯一的列d,并仅计算其中的不同值。我们不能选择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`

使用半连接

即使有多个匹配项,半连接也只返回一行结果在 SQL 中编写半联接的方法是这样的:

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`

半连接优化在 MySQL 5.6 中得到了改进,所以如果你使用这个解决方案,我建议升级。

于 2014-04-22T16:45:19.730 回答