mysql 防止WHERE在同一行上匹配

k3bvogb1  于 2023-05-05  发布在  Mysql
关注(0)|答案(2)|浏览(115)

我有一个包含两个表的数据库,shipsofficers。一个ship有多个officers。要搜索具有特定officership,我有一个类似于以下的查询:

SELECT a.id
FROM ships AS a 
LEFT JOIN bridge_officers AS aBoff ON a.id = aBoff.ship_id  
WHERE aBoff.profession = :aprofession
GROUP BY a.id

这将导致所有的ships都有一个officer,它有:aprofession。重复相同的JOIN/WHERE,以过滤多个officer
例如:

SELECT a.id
FROM ships AS a 
LEFT JOIN bridge_officers AS aBoff ON a.id = aBoff.ship_id
LEFT JOIN bridge_officers AS bBoff ON a.id = bBoff.ship_id
WHERE  aBoff.profession = :aprofession AND  bBoff.rank = :brank
GROUP BY a.id

这将导致所有的ships与具有:aprofession:brankofficers。我希望的行为是,只返回具有两个不同officers且符合这些条件的产品。如果一个officer同时拥有:aproffesion:brank,它将返回该船。我希望每个WHERE条件只匹配一个join。
有什么方法可以做到这一点吗?谢谢!

dphi5xsq

dphi5xsq1#

向第二个JOIN添加另一个条件,即它是不同的官员。

SELECT DISTINCT a.id
FROM ships AS a 
LEFT JOIN bridge_officers AS aBoff ON a.id = aBoff.ship_id
LEFT JOIN bridge_officers AS bBoff ON a.id = bBoff.ship_id AND aBoff.id != bBoff.id
WHERE  aBoff.profession = :aprofession AND  bBoff.rank = :brank
6uxekuva

6uxekuva2#

向联接条件中添加一个条件以防止同行匹配:

LEFT JOIN bridge_officers AS bBoff ON a.id = bBoff.ship_id
    AND aBoff.id < bBoff.id

选择<而不是!=来将中间结果集减半;仅产生任意两个军官的唯一组合。
另外,where子句中似乎有一个bug-您的问题指出 * 一个警官同时拥有:aproffusion和:brank*,但您的where子句

WHERE aBoff.profession = :aprofession
AND bBoff.rank = :brank

检查该人员是否作为某个职业,而该 * 其他 * 人员是否具有某个职级-似乎这些条件应适用于同一个连接表aBoff

WHERE aBoff.profession = :aprofession
AND aBoff.rank = :brank -- aBoff.rank, not bBoff.rank

您的查询还有另一个微妙的问题:通过将where子句应用于外部连接表,可以将它们转换为 inner joins,因为where子句为true的连接行必须存在(并被连接到),因此LEFT关键字在这里没有意义,为了清楚起见应该删除:

SELECT DISTINCT a.id
FROM ships AS a
JOIN bridge_officers AS aBoff ON a.id = aBoff.ship_id
JOIN bridge_officers AS bBoff ON a.id = bBoff.ship_id
  AND aBoff.id < bBoff.id
WHERE aBoff.profession = :aprofession
AND aBoff.rank = :brank

相关问题