Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 另一种改进SQL查询以避免联合的方法?_Mysql_Sql_Database - Fatal编程技术网

Mysql 另一种改进SQL查询以避免联合的方法?

Mysql 另一种改进SQL查询以避免联合的方法?,mysql,sql,database,Mysql,Sql,Database,用户可以通过邮政编码(例如:L14、L15、L16)或文本框中的位置进行搜索 如果用户输入“Liverpool”,它将找到位于“Liverpool”的所有商店。如果用户输入邮政编码(例如:L15),它将搜索所有在L15邮政编码区域内送货的商店 见下表: mysql> select * from shops; +----+----------+-----------+----------+ | id | name | location | postcode | +----+----

用户可以通过邮政编码(例如:L14、L15、L16)或文本框中的位置进行搜索

如果用户输入“Liverpool”,它将找到位于“Liverpool”的所有商店。如果用户输入邮政编码(例如:L15),它将搜索所有在L15邮政编码区域内送货的商店

见下表:

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挑战了其他人的说法,解决了与理论和其他人所说的不符的证据。