Mysql 另一种改进SQL查询以避免联合的方法?
用户可以通过邮政编码(例如:L14、L15、L16)或文本框中的位置进行搜索 如果用户输入“Liverpool”,它将找到位于“Liverpool”的所有商店。如果用户输入邮政编码(例如:L15),它将搜索所有在L15邮政编码区域内送货的商店 见下表:Mysql 另一种改进SQL查询以避免联合的方法?,mysql,sql,database,Mysql,Sql,Database,用户可以通过邮政编码(例如:L14、L15、L16)或文本框中的位置进行搜索 如果用户输入“Liverpool”,它将找到位于“Liverpool”的所有商店。如果用户输入邮政编码(例如:L15),它将搜索所有在L15邮政编码区域内送货的商店 见下表: mysql> select * from shops; +----+----------+-----------+----------+ | id | name | location | postcode | +----+----
mysql> select * from shops;
+----+----------+-----------+----------+
| id | name | location | postcode |
+----+----------+-----------+----------+
| 1 | Shop One | Liverpool | L10 |
| 2 | Shop Two | Liverpool | L16 |
+----+----------+-----------+----------+
-
SQL查询:
SELECT U.* FROM
((SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on (DA.shop_id = shops.id)
WHERE DA.postcode = "Liverpool")
UNION
(SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on
(DA.shop_id = shops.id AND
DA.postcode = shops.postcode)
WHERE shops.location = "Liverpool")) as U
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.50 | L10 |
| 2 | Shop Two | Liverpool | L16 | 0.00 | L16 |
+----+----------+-----------+----------+---------------+--------------+
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.00 | L12 |
+----+----------+-----------+----------+---------------+--------------+
-
结果-按地点(利物浦):
SELECT U.* FROM
((SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on (DA.shop_id = shops.id)
WHERE DA.postcode = "Liverpool")
UNION
(SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on
(DA.shop_id = shops.id AND
DA.postcode = shops.postcode)
WHERE shops.location = "Liverpool")) as U
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.50 | L10 |
| 2 | Shop Two | Liverpool | L16 | 0.00 | L16 |
+----+----------+-----------+----------+---------------+--------------+
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.00 | L12 |
+----+----------+-----------+----------+---------------+--------------+
结果-按邮政编码(L12):
SELECT U.* FROM
((SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on (DA.shop_id = shops.id)
WHERE DA.postcode = "Liverpool")
UNION
(SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on
(DA.shop_id = shops.id AND
DA.postcode = shops.postcode)
WHERE shops.location = "Liverpool")) as U
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.50 | L10 |
| 2 | Shop Two | Liverpool | L16 | 0.00 | L16 |
+----+----------+-----------+----------+---------------+--------------+
+----+----------+-----------+----------+---------------+--------------+
| id | name | location | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
| 1 | Shop One | Liverpool | L10 | 1.00 | L12 |
+----+----------+-----------+----------+---------------+--------------+
它似乎工作正常。。。
有没有其他方法可以缩短SQL查询以避免联合
或其他问题?我缺少什么?
你为什么不能呢
WHERE DA.postcode = "Liverpool" or shops.location = "Liverpool"
由于所有表和选定列都是相同的,您只需执行以下操作:
SELECT DISTINCT shops.*, DA.delivery_cost, DA.postcode AS AreaPostcode FROM shops
JOIN shops_delivery_area as DA on DA.shop_id = shops.id
WHERE (DA.postcode = "Liverpool")
OR (DA.postcode = shops.postcode AND shops.location = "Liverpool")
就像你在迭戈的回答中所说的,情况有点不同!因此,您可以在WHERE子句中补偿该差异,请尝试以下操作:
SELECT DISTINCT shops.*,
DA.delivery_cost,
DA.postcode
FROM shops
JOIN shops_delivery_area as DA on DA.shop_id = shops.id
WHERE DA.postcode = "Liverpool"
OR (location = "Liverpool" and DA.postcode = shops.postcode)
无论您选择什么,请注意短代码并不总是最佳代码。在许多情况下,当您有足够的分歧逻辑时,联合结果确实是最理想的(有时也是最干净的,编程上的)选择
也就是说,以下或WHERE条款似乎涵盖了您的两种情况
SELECT DISTINCT
shops.*,
DA.delivery_cost,
DA.postcode AS AreaPostcode
FROM
shops
INNER JOIN
shops_delivery_area as DA
ON (DA.shop_id = shops.id)
WHERE
(DA.postcode = "Liverpool")
OR
(DA.postcode = shops.postcode AND shops.location = "Liverpool")
这将不能正常工作,否则您将得到许多行相同的商店名称。仔细查看JOIN
。根据索引的使用方式,使用或
会降低性能。我通常会像这样将查询拆分为联合
,以避免出现或
,并通过在联合
的每个部分中使用一个索引来获得可观的性能增益@Diego,当它是shops.location=“Liverpool”时,您缺少一个限制
。只需在位置测试中添加另一个约束条件,以避免类似DA.postcode=shops.postcode的情况。您有什么理由避免使用联合
?p、 我想你可以删除DISTINCT
关键字,因为UNION
是UNION DISTINCT
的缩写。谢谢!那么,在性能方面,哪一个是更好的选择呢?坚持使用Union或或
中的WHERE子句,我刚刚做了性能测试。。使用Union
似乎更快。@user791022 said我刚刚做了性能测试。。使用Union似乎更快。
我早就告诉过你了。在一个表的中间进行两次索引命中或扫描整个表,什么速度更快?当您对SQL应用“应用程序”思想(减少冗余代码等)时,您会遇到性能问题。@KM.-虽然我在技术细节上同意你的观点,但我也只是在被证明是错误的情况下才学到了这个教训。随着我对SQL知识的增长,我寻找创新的方法来缩短代码。那时我发现了执行计划以及它们与我对SQL的理解之间的关系。我认为OP一直在寻找更好的方法是件好事。我甚至很高兴OP挑战了其他人的说法,解决了与理论和其他人所说的不符的证据。