mysql - 是否有更简洁的 SQL 查询来将两个值与单个可能性列表进行匹配?

标签 mysql sql

我支持的一个网站执行如下所示的 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 字段,以便查询返回居住 在任何指定城市工作。

最简单的方法就是简单地将“or”子句的数量加倍,如下所示:

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 查询本身的解决方案)

最佳答案

您应该使用 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 )

关于mysql - 是否有更简洁的 SQL 查询来将两个值与单个可能性列表进行匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19554790/

相关文章:

mysql - 如何简化我的sql查询

sql - 如何通过列名查找数据库名和表名

sql - 一次从大表中获取的最佳行大小

sql - 如何在SQL中选择 'previous'和 'next'记录?

mysql - SQL选择一列,SUM和ORDER BY使用三张表

mysql - 从表中选择,更新选择的行

php - Highscores(最高分)排名计算和更新查询?

java - 如何永久保存在SQLite数据库中

mysql - #1054 - 未知列 - SQL 查询问题

php - 显示数据库表中的动态范围并计算每个范围内的行数