SQL 中最强大的也是最复杂的就是查询部分。在需要查询多条记录时我们一般会采用 in 关键字来指定要查询的条件:
SELECT * FROM t_user WHERE uid IN (1,2,3,4,5,6,7,8,9);
但如果对应的数据需要两个或更多字段才能确定,可能会写出以下的 SQL 语句:
SELECT * FROM t_user WHERE (first_name = 'first_name_1' AND last_name = 'last_name_1') OR (first_name = 'first_name_2' AND last_name = 'last_name_2') OR (first_name = 'first_name_3' AND last_name = 'last_name_3') OR (first_name = 'first_name_4' AND last_name = 'last_name_4') OR (first_name = 'first_name_5' AND last_name = 'last_name_5') OR (first_name = 'first_name_6' AND last_name = 'last_name_6') OR (first_name = 'first_name_7' AND last_name = 'last_name_7');
以上代码当然能用,但拼接出来的语句过于复杂。有一个方法可以改善这个问题,就是使用多列 IN 的语法。
MySQL 中的多列 IN 查询
MySQL 是支持多列 IN 查询的,以上的 SQL 可以改写为:
SELECT * FROM t_user WHERE (first_name,last_name) IN ( ('first_name_1','last_name_1'), ('first_name_2','last_name_2'), ('first_name_3','last_name_3'), ('first_name_4','last_name_4'), ('first_name_5','last_name_5'), ('first_name_6','last_name_6'), ('first_name_7','last_name_7') );
需要注意的是,该写法在 MySQL 5.7 及以后的版本才被支持。
有关行构造表达式的信息可以参见这里:https://dev.mysql.com/doc/refman/5.7/en/row-constructor-optimization.html
有关行构造表达式的范围优化可以参见这里:https://dev.mysql.com/doc/refman/5.7/en/range-optimization.html#row-constructor-range-optimization
SQLite 中的多列 IN 查询
SQLite 也支持多列 IN 查询,只是语法上和 MySQL 有所不同,需要多加一个 VALUES 关键字:
SELECT * FROM t_user WHERE (first_name,last_name) IN ( VALUES ('first_name_1','last_name_1'), ('first_name_2','last_name_2'), ('first_name_3','last_name_3'), ('first_name_4','last_name_4'), ('first_name_5','last_name_5'), ('first_name_6','last_name_6'), ('first_name_7','last_name_7') );
PostgreSQL 中的多列 IN 查询
PostgreSQL 也支持队列 IN 查询,在官方文档中,这种形式被称为“行构造器”,参见:PostgreSQL 子查询表达式 。其多列查询的语法和 MySQL 相同:
SELECT * FROM t_user WHERE (first_name,last_name) IN ( ('first_name_1','last_name_1'), ('first_name_2','last_name_2'), ('first_name_3','last_name_3'), ('first_name_4','last_name_4'), ('first_name_5','last_name_5'), ('first_name_6','last_name_6'), ('first_name_7','last_name_7') );
Oracel 中的多列 IN 查询
Oracel 中的多列 IN 查询语法和 MySQL 一致,感谢 @shakoon 提供支持。
SELECT * FROM AREA_MAP WHERE (PROV_ID, AREA_ID) IN (('京', 'A'), ('粤', 'B'));
其他数据库对多列 IN 查询的支持情况
多列 IN 并非受所有数据库支持。根据网上的资料 SQL Server 不支持。其他数据库的支持情况因笔者没有测试环境,并未进行测试。