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

PostgreSQL 可以将 json 数组中的某一个值做为条件查询吗?

  •  
  •   imherer · 2019-10-11 16:11:56 +08:00 · 6024 次点击
    这是一个创建于 1875 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下字段: id,name,category,其中 category 类型是 jsonb 假如有如下 3 行数据:

    • 1001, name1, [11, 22, 33]
    • 1002, name2, [44, 55, 66]
    • 1003, name3, [33, 77, 88]

    想要的结果是:

    where category=11 的时候返回 1001 这一行数据

    where category=33 的时候返回 1001 和 1003 两行数据

    16 条回复    2020-01-02 16:33:58 +08:00
    javapythongo
        1
    javapythongo  
       2019-10-11 16:27:11 +08:00
    可以的
    imherer
        2
    imherer  
    OP
       2019-10-11 16:31:16 +08:00
    @javapythongo 该怎么写上面的 sql 呢?

    我现在用 jsonb_array_elements_text 函数实现了想要的结果了,但是不知道有没有什么问题
    reus
        3
    reus  
       2019-10-11 16:34:16 +08:00
    where category && array[11]
    randm
        4
    randm  
       2019-10-11 16:37:57 +08:00
    数据都没有 KEY 键,很难定位
    https://www.postgresql.org/docs/12/functions-json.html
    reus
        5
    reus  
       2019-10-11 16:38:43 +08:00
    看错了,json 要用 @>

    select category @> '11'::jsonb
    reus
        6
    reus  
       2019-10-11 16:39:18 +08:00
    @randm @> 可以用在 array 上
    imherer
        7
    imherer  
    OP
       2019-10-11 16:39:31 +08:00
    @reus 报语法错误 operator does not exist: jsonb && integer[]
    reus
        8
    reus  
       2019-10-11 16:40:40 +08:00   ❤️ 1
    @imherer 看后面的,用 @>

    && 是用在数组类型的,不是 jsonb 类型
    optional
        9
    optional  
       2019-10-11 16:40:55 +08:00   ❤️ 1
    category @> '22'::jsonb 这样。
    如果是字符串数组就更简单 category ? '22'
    imherer
        10
    imherer  
    OP
       2019-10-11 16:41:31 +08:00
    @reus 感谢,这样写可以的。

    我现在是这样写的,也能得到想要的结果,不知道有没有什么问题
    SELECT * FROM table,jsonb_array_elements_text(category) c WHERE c =111;

    @randm
    reus
        11
    reus  
       2019-10-11 16:44:58 +08:00   ❤️ 1
    @imherer @> 加上索引,是效率最高的。你这个又要 join 又要转换成 text,可能会出现效率很低的执行计划。
    randm
        12
    randm  
       2019-10-11 16:51:49 +08:00   ❤️ 1
    补上,有字段名,那应该可以的
    WHERE category @> '[11]'::jsonb
    imherer
        13
    imherer  
    OP
       2019-10-11 16:53:31 +08:00
    @optional 我尝试把字段改成字符串数组后,报语法错误呢 operator does not exist: character varying[] ? unknown

    改了之后的源数据是这样的

    1001, name1, {11, 22, 33}
    optional
        14
    optional  
       2019-10-11 17:28:28 +08:00   ❤️ 1
    @imherer text[] 用 @> array['11'] , 带 orderby 的时候 text[] 优于 jsonb array
    imherer
        15
    imherer  
    OP
       2019-10-11 17:36:00 +08:00
    @optional ?只能 jsonb 才能用把 好像?
    encro
        16
    encro  
       2020-01-02 16:33:58 +08:00
    category 可以用 array[int]类型,然后加 Gist 索引
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3251 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:43 · PVG 20:43 · LAX 04:43 · JFK 07:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.