Soar360
V2EX  ›  数据库

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

  •  
  •   Soar360 · Jul 5, 2022 · 3215 views
    This topic created in 1584 days ago, the information mentioned may be changed or developed.
    Supplement 1  ·  Jul 5, 2022

    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')
    );
    
    Supplement 2  ·  Jul 5, 2022

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

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

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

    讨论的话,应该写详细电,比如<强大的多列 IN 查询语句,及数据库支持情况>
    强大,哪里强大了?是因为能走索引还是啥的,有没其他相同的查询方式,对比如何
    哪些支持,哪些不支持?别只说支持的,深入可用说为什么支持,为什么不支持,支持的差异
    这些才是最有讨论价值的吧?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5523 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 76ms · UTC 02:59 · PVG 10:59 · LAX 18:59 · JFK 21:59
    ♥ Do have faith in what you're doing.