我有一张邮政编码表:
id INT, postcode VARCHAR(8)
和那些只存储两个不同邮政编码之间的一个方向距离的邮政编码之间的距离表,所以从邮编ID 2到邮编ID 5,距离只存储为2, 5, 78.2
或{{{ 1}}但不是两者。
5, 2, 78.2
距离上的主键是(from,to),我对该表中的每一列都有一个索引。
我有一个如下所示的查询:
from INT, to INT, dist DECIMAL
查询运行缓慢(正如您可能预期的那样)并将数据库锁定为副作用。
解析查询会显示postcode_distances join的此行:
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;
在单个查询中,有什么方法可以实现两个连接(在1 | SIMPLE | postcode_distances | ALL | PRIMARY,dist,to,from | 695332 | Using where; Using join buffer
或from
列中搜索的邮政编码是什么?
我可以使用UNION并只运行查询两次,但是在每个查询中都放了postcode_distance OR条件的每一半,但我想检查一下我是否错过了另一种更简单的方式这样做?
答案 0 :(得分:1)
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;
答案 1 :(得分:0)
如果发现错误,请尝试此评论
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;
答案 2 :(得分:0)
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;
答案 3 :(得分:0)
这是一种不同的方法:
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
查询使用外部联接到listings
的特定子集,并检索在该子集中具有匹配项或具有特定postcode
的行。然后对行进行分组,确保组恰好有两行。