简体   繁体   English

MYSQL查询双联接

[英]MYSQL Query double JOIN

This is my query: 这是我的查询:

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`

Now when I check my table psttodo-in in Sequal Pro and I select the rows where Segment No_ PST = PSS1400146 and Deelgebied = 2 I count 84 . 现在,当我在Sequal Pro中检查我的表psttodo-in时,我选择了Segment No_ PST = PSS1400146Deelgebied = 2的行,我数为84 But when I run the query I get a result of 252 . 但是当我运行查询时,得到的结果是252 What am I doing wrong? 我究竟做错了什么?

UPDATE : 更新

My table structure : 我的表结构:

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

There's always exactly one row in d for each row in p , because of the foreign key reference. 总有恰好一列d在每一行p ,由于外键引用。

But there may be multiple rows in m2m for each or in d . 但是每个m2md可能有多个行。 In fact, since 252 is 84 * 3, I would guess that there are three rows in m2m for each d (or at least the average is three). 实际上,由于252为84 * 3,所以我想对于每个dm2m中有三行(或者至少平均值为三行)。 Thus in the joined result set, the rows are tripled, with distinct rows from m2m but the rows from p and d are repeated. 因此,在合并的结果集中,行的数量增加了三倍,与m2m的行不同,但重复了pd的行。

There are a couple of ways to fix this: 有两种方法可以解决此问题:

Count each p only once 每个p只计数一次

We know that in the repeated rows, the values from p and d are repeated. 我们知道在重复的行中,来自pd的值是重复的。 So pick a column that is known to be unique in either p or d , and count only the distinct values in it. 因此,选择一个在pd唯一的列,并仅计算其中的不同值。 We can't pick d because those might be chosen more than once legitimately, if two different p entries reference the same d . 我们不能选择d因为如果两个不同的p条目引用相同的d ,那么可能会多次合法地选择它们。 So pick the primary key of p : 因此,选择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`

Use a semi-join 使用半联接

A semi-join returns only one row of the result even if there are multiple matches. 即使存在多个匹配项, 联接也仅返回结果的一行。 The way to write a semi-join in SQL is like this: 在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`

Semi-join optimization was improved in MySQL 5.6, so I recommend upgrading if you use this solution. 半联接优化在MySQL 5.6中得到了改进,因此,如果您使用此解决方案,建议升级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM