V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Soar360
V2EX  ›  数据库

强大的多列 IN 查询语句,及数据库支持情况。

  •  
  •   Soar360 · 2022-07-05 09:31:37 +08:00 · 2220 次点击
    这是一个创建于 864 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言  ·  2022-07-05 11:16:47 +08:00

    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')
    );
    

    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 相同:

        ('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')
    );
    
    第 2 条附言  ·  2022-07-05 11:16:55 +08:00

    其他数据库对多列 IN 查询的支持情况

    多列 IN 并非受所有数据库支持。根据网上的资料,Oracel 是支持该操作的,但 SQL Server 不支持。其他数据库的支持情况因笔者没有测试环境,并未进行测试。

    15 条回复    2022-07-06 11:14:51 +08:00
    cccssss
        1
    cccssss  
       2022-07-05 09:32:36 +08:00
    驴唇不对马嘴,大家不用点进去看了,做广告的
    Soar360
        2
    Soar360  
    OP
       2022-07-05 09:36:22 +08:00
    @cccssss ### l 链接贴错了……
    chengyiqun
        3
    chengyiqun  
       2022-07-05 09:41:41 +08:00
    就不能完整的例子贴出来, 文末附上链接吗?
    autosevenpp
        4
    autosevenpp  
       2022-07-05 10:27:25 +08:00
    50 分钟了,还是没贴上正确的链接
    GeorgeGalway
        5
    GeorgeGalway  
       2022-07-05 10:27:30 +08:00
    很有帮助,谢谢楼主,多列 IN 的语法也是第一次见到,学习到了
    Soar360
        6
    Soar360  
    OP
       2022-07-05 10:40:07 +08:00
    @autosevenpp 已经改了啊,是正确的地址啊。
    shakoon
        7
    shakoon  
       2022-07-05 11:26:09 +08:00   ❤️ 1
    oracle 的写法和 mysql 一样的,例如
    SELECT *
    FROM AREA_MAP
    WHERE (PROV_ID, AREA_ID) IN (('京', 'A'), ('粤', 'B'))
    Soar360
        8
    Soar360  
    OP
       2022-07-05 11:27:20 +08:00
    @shakoon 好的,谢谢大佬。
    xiangyuecn
        9
    xiangyuecn  
       2022-07-05 11:44:56 +08:00
    学不动了,我还是喜欢最朴素的做法,没有心智负担😂
    canbingzt
        10
    canbingzt  
       2022-07-05 14:22:27 +08:00
    mysql 是从哪个版本开始支持的?
    freelancher
        11
    freelancher  
       2022-07-05 15:52:16 +08:00
    举的例子差一点都看不懂了。写得什么东西?自己能先看一下吗?
    MoYi123
        12
    MoYi123  
       2022-07-05 16:55:51 +08:00
    把大伙叫出来就这点事啊.
    Leviathann
        13
    Leviathann  
       2022-07-05 17:06:31 +08:00
    mysql 5.7 以前这样查不支持索引
    Soar360
        14
    Soar360  
    OP
       2022-07-05 17:10:07 +08:00
    @canbingzt
    @Leviathann
    翻了下 MySQL 的文档,是要到 5.7 及以后才行。
    https://dev.mysql.com/doc/refman/5.7/en/row-constructor-optimization.html
    KaGaMiKun
        15
    KaGaMiKun  
       2022-07-06 11:14:51 +08:00
    感觉写个博客放放还差不多

    讨论的话,应该写详细电,比如<强大的多列 IN 查询语句,及数据库支持情况>
    强大,哪里强大了?是因为能走索引还是啥的,有没其他相同的查询方式,对比如何
    哪些支持,哪些不支持?别只说支持的,深入可用说为什么支持,为什么不支持,支持的差异
    这些才是最有讨论价值的吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5297 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:20 · PVG 15:20 · LAX 23:20 · JFK 02:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.