同一个表上的MySQL重复联接

同一个表上的MySQL重复联接,mysql,sql,join,Mysql,Sql,Join,我有一张邮政编码表: id INT, postcode VARCHAR(8) 以及这些邮政编码之间的距离表,该表仅存储两个不同邮政编码之间在一个方向上的距离,因此从邮政编码ID 2到邮政编码ID 5,该距离仅存储为2,5,78.2或5,2,78.2,但不能同时存储为两者 from INT, to INT, dist DECIMAL 距离的主键是(from,to),表中的每一列都有索引 我有一个如下的查询: SELECT * FROM listings, postcode_distances,

我有一张邮政编码表:

id INT, postcode VARCHAR(8)
以及这些邮政编码之间的距离表,该表仅存储两个不同邮政编码之间在一个方向上的距离,因此从邮政编码ID 2到邮政编码ID 5,该距离仅存储为
2,5,78.2
5,2,78.2
,但不能同时存储为两者

from INT, to INT, dist DECIMAL
距离的主键是(from,to),表中的每一列都有索引

我有一个如下的查询:

SELECT *
FROM listings, postcode_distances,
     postcodes postcode_listings, postcodes postcode_searchterm
WHERE listing.`status` = 3
AND listings.category = 8
AND postcode_listings.id = listings.postcode_id
AND (
     (postcode_distances.to = postcode_listings.id AND
      postcode_distances.from = postcode_searchterm.id AND
      postcode_distances.dist < 30)
     OR
     (postcode_distances.from = postcode_listings.id AND
      postcode_distances.to = postcode_searchterm.id AND
      postcode_distances.dist < 30)
)
AND postcode_searchterm.postcode = 'AB11'
GROUP BY id_listings
ORDER BY postcode_distances.dist ASC;
是否有任何方法可以在单个查询中实现两个连接(其中搜索的邮政编码是
from
to
列)

我可以使用UNION并只运行两次查询,但将每一半的邮政编码距离或条件放入每个查询中,但我想检查是否遗漏了另一种更简单的方法?

选择postcodes.id作为searchedd,
SELECT postcodes.id       AS SearchedId, 
       postcodes.postcode AS SearchedPostCode, 
       p1.postcode        AS FromPostCode, 
       p2.postcode        AS ToPostCode, 
       p1.id              AS FromPostCodeId, 
       p2.id              AS ToPostCodeId, 
       postcode_distances.dist 
FROM   listings 
       INNER JOIN postcodes 
         ON postcodes.id = listings.postcode_id 
       INNER JOIN postcode_distances 
         ON ( postcode_distances.to1 = postcodes.id 
               OR postcode_distances.from1 = postcodes.id ) 
       INNER JOIN postcodes p1 
         ON postcode_distances.From1 = p1.id 
       INNER JOIN postcodes p2 
         ON postcode_distances.to1 = p2.id 
WHERE  listings.status = 3 
       AND listings.category = 8 
       AND postcode_distances.dist < 30 
       AND postcodes.postcode = 'AB11' 
ORDER  BY postcode_distances.dist ASC; 
邮政编码。邮政编码作为搜索的邮政编码, p1.邮政编码与邮政编码相同, p2.邮政编码为ToPostCode, p1.id作为邮政编码id, p2.id作为ToPostCodeId, 邮政编码_.dist 来自列表 内部联接邮政编码 在postcodes.id=listings.postcode\u id上 内部连接邮政编码 ON(postcode_.to1=postcodes.id 或邮政编码_.from1=邮政编码.id) 内部联接邮政编码p1 关于邮政编码_.From1=p1.id 内部联接邮政编码p2 邮政编码_.to1=p2.id 其中listings.status=3 AND listings.category=8 邮政编码_.dist<30 和邮政编码。邮政编码='AB11' 按邮政编码_distance.ASC排序;

如果发现问题,请尝试此评论

 select * from listings, postcode_distances pDis,postcodes post
 WHERE listing.status = 3 AND listings.category = 8
 AND (pDis.to = post.id OR pDis.from = post.id) AND post.postcode = 'AB11' 
 AND pDis.dist < 30;
从列表、邮政编码、PDI和邮政编码中选择*
其中listing.status=3,listings.category=8
和(pDis.to=post.id或pDis.from=post.id)和post.postcode='AB11'
pDis.dist<30;
选择*
来自列表
在postcode_listings.id=listings.postcode_id上加入邮政编码postcode_列表
加入邮政编码邮政编码搜索术语
连接邮政编码
在((listings.postcode\u id,postcode\u searchterm.id)
在(
(邮政编码至,邮政编码至),
(邮政编码距离,邮政编码距离到)
)
邮政编码_.dist<30
)
其中listings.status=3
AND listings.category=8
邮政编码_searchterm.postcode='AB11'
按id分组\u列表
按邮政编码_distance.ASC排序;

这里有一种不同的方法:

SELECT
  MAX(CASE p.id WHEN d.`from` THEN p.postcode END) AS from_postcode,
  MAX(CASE p.id WHEN d.`to`   THEN p.postcode END) AS to_postcode,
  d.`from`,
  d.`to`,
  d.`dist`,
  MAX(l.id_listings) AS id_listings
FROM postcode_distances d
INNER JOIN postcodes p ON p.id IN (d.`from`, d.`to`)
LEFT JOIN listings l ON l.postcode_id = p.id AND l.`status` = 3 AND l.category = 8
WHERE p.postcode =  'AB11' AND l.id_listings IS     NULL
   OR p.postcode <> 'AB11' AND l.id_listings IS NOT NULL
GROUP BY
  d.`from`,
  d.`to`,
  d.`dist`
HAVING COUNT(*) = 2
选择
最大值(d.`from`时的案例p.id,然后p.postcode END)为from_postcode,
MAX(d.`to`时的案例p.id,然后p.postcode END)作为邮政编码,
d、 “从”,
d、 “到”,
d、 'dist`,
最大值(l.id\U列表)作为id\U列表
来自邮政编码(d)
(d.`from`,d.`to`)中p.id上的内部联接邮政编码p
左连接l.postcode_id=p.id和l.`status`=3和l.category=8上的清单l
其中p.postcode='AB11'和l.id\u列表为空
或p.邮政编码“AB11”和l.id_列表不为空
分组
d、 “从”,
d、 “到”,
d、 “距离`
计数(*)等于2的

查询使用到
列表的特定子集的外部联接
,并检索在该子集中具有匹配项或具有特定
邮政编码的行
。这些行然后被分组,并且保证组有两行。

您应该考虑使用表之间的连接语法,而不是逗号。@谢谢BROWFROW,我知道我没有使用正确的语法,而且我的列名是保留词。这将限制结果只显示AB11的邮政编码列表。我需要显示30英里内的邮政编码列表AB11@Jon,您是否尝试了对数据库的查询。它将显示AB11的所有邮政编码,这些邮政编码在30英里以下。是的,它不起作用。您在这里的连接将
列表限制为仅包含邮政编码id等于'AB11'的列表,谢谢-以前从未遇到过sqlfiddle!如果您可以让查询从这组结果中列出与邮政编码ID 3、6和4匹配的邮政编码,那么您就完成了!(注意3在“收件人”列中,6和4在“发件人”列中)参考所需的解决方案并检查更新的答案。几乎。。。但是
postcode\u distance.from=listings.postcode\u id
也需要在那里,因为如果postcode\u搜索词与postcode\u distance中的
to
列相匹配,那么我希望列表中的结果与
from
中的id相匹配。乔恩:啊,我误解了你问题中的查询。看我修改过的答案。
SELECT   *
FROM     listings
  JOIN   postcodes postcode_listings ON postcode_listings.id = listings.postcode_id
  JOIN   postcodes postcode_searchterm
  JOIN   postcode_distances
    ON ( (listings.postcode_id, postcode_searchterm.id)
         IN (
           (postcode_distances.to,   postcode_distances.from),
           (postcode_distances.from, postcode_distances.to)
         )
     AND postcode_distances.dist < 30
    )
WHERE    listings.status = 3
     AND listings.category = 8
     AND postcode_searchterm.postcode = 'AB11'
GROUP BY id_listings
ORDER BY postcode_distances.dist ASC;
SELECT
  MAX(CASE p.id WHEN d.`from` THEN p.postcode END) AS from_postcode,
  MAX(CASE p.id WHEN d.`to`   THEN p.postcode END) AS to_postcode,
  d.`from`,
  d.`to`,
  d.`dist`,
  MAX(l.id_listings) AS id_listings
FROM postcode_distances d
INNER JOIN postcodes p ON p.id IN (d.`from`, d.`to`)
LEFT JOIN listings l ON l.postcode_id = p.id AND l.`status` = 3 AND l.category = 8
WHERE p.postcode =  'AB11' AND l.id_listings IS     NULL
   OR p.postcode <> 'AB11' AND l.id_listings IS NOT NULL
GROUP BY
  d.`from`,
  d.`to`,
  d.`dist`
HAVING COUNT(*) = 2