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

I'l*_*ack 8 mysql sql database

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

如果用户输入"利物浦",它将找到位于"利物浦"的所有商店.如果用户输入邮政编码(例如:L15),它将搜索在L15邮政编码区域内交货的所有商店.

见下表:

mysql> select * from shops;
+----+----------+-----------+----------+
| id | name     | location  | postcode |
+----+----------+-----------+----------+
|  1 | Shop One | Liverpool | L10      |
|  2 | Shop Two | Liverpool | L16      |
+----+----------+-----------+----------+
Run Code Online (Sandbox Code Playgroud)

-

mysql> select * from shops_delivery_area;
+------------------+---------+----------+---------------+
| delivery_area_id | shop_id | postcode | delivery_cost |
+------------------+---------+----------+---------------+
|                1 |       1 | L10      |          1.50 |
|                2 |       1 | L11      |          0.00 |
|                3 |       1 | L12      |          1.00 |
|                4 |       1 | L13      |          1.00 |
|                5 |       2 | L10      |          2.50 |
|                6 |       2 | L16      |          0.00 |
|                7 |       2 | L28      |          0.00 |
+------------------+---------+----------+---------------+
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

-

结果 - 按地点(利物浦):

+----+----------+-----------+----------+---------------+--------------+
| id | name     | location  | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
|  1 | Shop One | Liverpool | L10      |          1.50 | L10          |
|  2 | Shop Two | Liverpool | L16      |          0.00 | L16          |
+----+----------+-----------+----------+---------------+--------------+
Run Code Online (Sandbox Code Playgroud)

结果 - 按邮政编码(L12):

+----+----------+-----------+----------+---------------+--------------+
| id | name     | location  | postcode | delivery_cost | AreaPostcode |
+----+----------+-----------+----------+---------------+--------------+
|  1 | Shop One | Liverpool | L10      |          1.00 | L12          |
+----+----------+-----------+----------+---------------+--------------+
Run Code Online (Sandbox Code Playgroud)

它似乎工作正常...有没有其他方法来改善SQL查询更短,以避免union或什么?

Mat*_*lie 2

无论您选择什么,请注意短代码并不总是最佳代码。在许多情况下,当逻辑足够不同时,合并结果确实是最优化的(有时也是最干净的、以编程方式)的选择。

也就是说,WHERE 子句中的以下 OR 似乎涵盖了您的两种情况......

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")
Run Code Online (Sandbox Code Playgroud)