0

我支持的网站执行如下所示的 MySQL 数据库查询:

SELECT 
   person_per.per_ID 
FROM 
   person_per 
LEFT JOIN 
   person_custom 
ON 
   person_custom.per_ID=person_per.per_ID 
where 
   (per_City='Cathedral City') or 
   (per_City='Cherry Valley') or 
   (per_City='Coachella') or 
   [...and so on for several dozen cities...];

该查询应该返回居住在任何指定城市列表中的一组人。该查询既丑陋又冗长,但工作正常。

但是,新请求是修改查询,使其不仅检查 person_per.per_City 字段,还检查 person_custom.work_City 字段,以便查询返回在任何指定城市生活或工作的任何人。

这样做的天真方法是将“或”子句的数量简单地增加一倍,如下所示:

SELECT 
  person_per.per_ID 
FROM 
  person_per 
LEFT JOIN 
  person_custom 
ON 
  person_custom.per_ID=person_per.per_ID 
where 
  (per_City='Cathedral City') or 
  (work_City='Cathedral City') or 
  (per_City='Coachella') or 
  (work_City='Coachella') or 
  [...and so on for several dozen cities...];

但如果可能的话,我想避免这样做,因为唯一比包含整个城市名称列表的 20 行 SQL 查询更糟糕的是包含两次完整城市名称列表的 40 行 SQL 查询. 该查询将(甚至更)难以编写和维护。

那么,有没有办法对这个两列查询进行表述,使得每个城市的名称在查询中只出现一次?(我知道我可以创建一个城市名称的 SQL 表,但如果可能的话,我宁愿不修改应用程序的 SQL 表集,所以我更喜欢只修改 SQL 查询本身的解决方案)

4

2 回答 2

1

您应该使用IN运算符来检查一个值是否在其他值的列表中,因此第一个查询将简化为:

   SELECT person_per.per_ID
     FROM person_per 
LEFT JOIN person_custom USING(per_ID)
    WHERE per_City IN ( 'Cathedral City', 'Cherry Valley', 'Coachella', ... )

对于第二个查询,我建议将城市列表存储在表中或变量中以减少重复。查询的表版本如下所示:

   SELECT person_per.per_ID
     FROM person_per 
LEFT JOIN person_custom USING(per_ID)
    WHERE per_City  IN ( SELECT cities_City FROM cities )
       OR work_City IN ( SELECT cities_City FROM cities )
于 2013-10-24T00:46:50.033 回答
0

如评论中所述,使用“in”运算符:

SELECT 
  person_per.per_ID 
FROM 
  person_per 
LEFT JOIN 
  person_custom 
ON 
  person_custom.per_ID=person_per.per_ID 
where 
  per_City in ('Cathedral City','Coachella', 'city1', 'city2', ...) OR 
  work_City in ('Cathedral City','Coachella', 'city1', 'city2', ...)

每种编程语言都可以轻松构建逗号分隔的字符串,因此您不必为此做太多工作。

于 2013-10-24T00:41:09.120 回答