mysql - 在 SQL 查询中的 WHERE 语句中具有条件
问题描述
我有两个查询返回相同的列集。
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME IN ('123')
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE B.Address IN ('123')
如果用户输入 first_name 作为输入,则必须选择第一个查询的结果,如果用户输入 Address 作为输入,则必须选择第二个查询的结果。
当用户给出名字时,我尝试使用 (A.FIRST_NAME = '123' or B.Address = ''),当用户给出中间名时,我尝试使用 (A.FIRST_NAME = '' or B.Address = '123') 但是它使查询永远运行。
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME IN ('') OR B.Address IN ('123')
我想听听我的同行专家的建议。
解决方案
典型的方法是这样的:
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE (a.first_name = @first_name OR @first_name IS NULL)
AND (a.address = @address OR @address IS NULL);
这适用于
- 只给出名字
- 只给出地址
- 两者都给出(在这种情况下,只返回匹配两个条件的行)
- 没有给出(在这种情况下,所有行都被返回)
DBMS 必须找到适用于所有条件的执行计划。这可能是不一定很慢的全表扫描,但这也不会很快。
这与UNION
查询不同:
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE a.first_name = @first_name
UNION
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE a.address = @address;
这适用于
- 只给出名字
- 只给出地址
- 两者都给出(在这种情况下,所有匹配至少一个条件的行都会返回)
- 没有给出(在这种情况下不返回任何行)
对于这个查询,DBMS 可以使用一个索引first_name
和另一个索引address
(前提是您创建了这些索引)并且查询将非常快。
这个UNION
查询毕竟只是另一种巧妙地使用该WHERE
子句的方式WHERE a.first_name = @first_name OR a.address = @address
。但是通过拆分查询,您可以向 DBMS 的优化器提示它可以将其视为两个单独的查询,它可以使用不同的索引。有了完美的优化器,这个提示就没有必要了,DBMS 会自己看到。我很确定 MySQL 当前的优化器需要这个提示。)
推荐阅读
- c# - 从没有 DeserializeObject C# 的 Json 中获取值
- javascript - 在节点js中将html表单转换为pdf?
- postgresql - PostgreSQL Update TRIGGER 仅在更新 1 行时触发多次
- javascript - 如何获得 FCM 代币?
- intellij-idea - 在 HTTP 客户端 IntelliJ IDEA 中发送 cookie
- ios - 有没有办法(软件或库)捕获iOS / android手机发出的HTTP请求(标题+正文)并分析它
- c# - 如何根据 C# 中的用户登录类型隐藏主菜单按钮
- php - 为什么 index.php 在 codeigniter 中以第一段为前缀的 url 有效 | 代码点火器 | 重写条件
- pluralize - 如何为 weblate 翻译文件添加复数形式?
- c# - 如何传递 IEnumerable 数组
在 ASP.NET MVC 中正确地从一个视图到另一个视图?