【问题标题】:MYSQL Query double JOINMYSQL查询双JOIN
【发布时间】:2014-04-22 16:17:34
【问题描述】:

这是我的查询:

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

【问题讨论】:

  • 其他表中的多条记录与您的ON-clauses 匹配。
  • 我不明白...我该如何解决这个问题?
  • 这取决于您的表结构,请分享它们以便提供足够的信息以便我们分析问题。
  • 找到一种更好的方法来过滤连接表中的行,添加额外的子句来识别唯一记录。
  • 您的联接将返回两个表中的所有匹配记录。您在 psttodo-in 中可能只有 84 条记录,但显然 OTHER 表中有多个匹配记录。例如如果 pstoddo-in 有记录 (a,b),并且连接带回 (a,b,1)(a,b,2),则您的 pstoddo-in 计数为 1,但您仍有两条记录。

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


【解决方案1】:

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

m2m 中的每个或d 中可能有多个行。实际上,由于 252 是 84 * 3,我猜想每个 m2m 中有三行 d(或者至少平均值是三行)。因此,在连接的结果集中,行增加了三倍,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`

使用半联接

即使有多个匹配项,semi-join 也只返回一行结果。 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 中改进了半连接优化,因此如果您使用此解决方案,我建议升级。

【讨论】:

    猜你喜欢
    • 2011-09-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2010-09-14
    相关资源
    最近更新 更多