【问题标题】:PostgreSQL query on text array valuePostgreSQL 查询文本数组值
【发布时间】:2012-09-14 23:34:22
【问题描述】:

我有一个表格,其中一列有一个数组 - 但以文本格式存储:

mytable

id  ids
--  -------
1   '[3,4]'
2   '[3,5]'
3   '[3]'
etc ...

我想在 ids 列中查找所有值 5 作为数组元素的记录。

我试图通过使用“字符串到数组”函数并使用translate 函数删除[ 符号来实现这一点,但找不到方法。

【问题讨论】:

    标签: sql arrays postgresql


    【解决方案1】:

    您可以这样做:http://www.sqlfiddle.com/#!1/5c148/12

    select *
    from tbl
    where translate(ids, '[]','{}')::int[] && array[5];
    

    输出:

    | ID |   IDS |
    --------------
    |  2 | [3,5] |
    

    也可以使用 bool_or:http://www.sqlfiddle.com/#!1/5c148/11

    with a as
    (
      select id, unnest(translate(ids, '[]','{}')::int[]) as elem
      from tbl
    )
    select id
    from a
    group by id
    having bool_or(elem = 5);
    

    查看原始元素:

    with a as
    (
      select id, unnest(translate(ids, '[]','{}')::int[]) as elem
      from tbl
    )
    select id, '[' || array_to_string(array_agg(elem), ',') || ']' as ids
    from a
    group by id
    having bool_or(elem = 5);
    

    输出:

    | ID |   IDS |
    --------------
    |  2 | [3,5] |
    

    Postgresql DDL 是原子的,如果在您的项目中还不晚,只需将您的字符串类型数组构造成一个真实数组:http://www.sqlfiddle.com/#!1/6e18c/2

    alter table tbl
    add column id_array int[];
    
    update tbl set id_array = translate(ids,'[]','{}')::int[];
    
    alter table tbl drop column ids;
    

    查询:

    select *
    from tbl
    where id_array && array[5]
    

    输出:

    | ID | ID_ARRAY |
    -----------------
    |  2 |      3,5 |
    

    您也可以使用包含运算符:http://www.sqlfiddle.com/#!1/6e18c/6

    select *
    from tbl
    where id_array @> array[5];
    

    我更喜欢&& 语法,它直接表示交集。它反映您正在检测两个集合之间是否存在交集(数组是一个集合)

    http://www.postgresql.org/docs/8.2/static/functions-array.html

    【讨论】:

    • 非常感谢,其实还不算晚,我会努力说服这个字段改成真正的数组,非常感谢您的帮助
    【解决方案2】:

    如果您存储数组的字符串表示形式略有不同,您可以直接转换为array of integer

    INSERT INTO mytable
    VALUES 
     (1, '{3,4}')
    ,(2, '{3,5}')
    ,(3, '{3}');
    
    SELECT id, ids::int[]
    FROM   mytable;
    

    否则,您必须多做一步:

    SELECT (translate(ids, '[]','{}'))::int[]
    FROM   mytable
    

    我会考虑将列作为数组类型开始。

    无论哪种方式,您都可以像这样找到您的行:

    SELECT id, ids 
    FROM  (
        SELECT id, ids, unnest(ids::int[]) AS elem
        FROM   mytable
        ) x
    WHERE  elem = 5
    

    【讨论】:

    • 同意,但如果他可以编辑数据库结构,他最好将这些 ID 完全存储在单独的字段中。
    • @sudowned:或者甚至在一个单独的表中,每行一个数字。但我们确实没有足够的信息来确定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多