PostgreSQL字符串的一部分是在一个数组中

时间:2017-04-13 20:33:12

标签: sql postgresql

我正在尝试获取其部分ID在定义列表中的值。假设我们有一个名为ABC

的表格
CREATE TABLE abc
AS
  SELECT post_id
  FROM ( VALUES 
    ( '868164246578472_912876412107255' ),
    ( '868164246578472_912883258773237' ),
    ( '868164246578472_913049595423270' )
  ) AS t(post_id);

然后我只是参加了下划线

select (regexp_split_to_array(element_id, '_'))[2] as element_id from ABC limit 3;
        element_id     
    -----------------
     912876412107255
     912883258773237
     913049595423270 

现在我想只采用那些元素,其中element_ids在一个已定义的列表中,但我没有得到任何结果

select (regexp_split_to_array(post_id, '_'))[2] as post_id from ABC where post_id = ANY('{912876412107255, 912883258773237}'::text[]) limit 3;
 post_id 
---------
(0 rows)

我也试过这个:

select (regexp_split_to_array(post_id, '_'))[2]::text[] as post_id from ABC where post_id IN ('912876412107255', '912876412107255') limit 3;
 post_id 
---------
(0 rows)

表的结构如下:

Table "public.ABC"
    Column     |            Type             |                      Modifiers                       
---------------+-----------------------------+------------------------------------------------------
 id            | integer                     | not null default nextval('ABC_id_seq'::regclass)
 element_id    | text                        | not null

4 个答案:

答案 0 :(得分:2)

使用比正则表达式功能便宜得多的函数string_to_array()

您应该使用WHERE子句中的表达式:

select (string_to_array(post_id, '_'))[2] as post_id
from abc
where (string_to_array(post_id, '_'))[2] = any('{912876412107255, 912883258773237}');

或派生表:

select post_id
from (
    select (string_to_array(post_id, '_'))[2] as post_id
    from abc
    ) s
where post_id = any('{912876412107255, 912883258773237}');

派生表不会产生额外费用,查询是等效的。

更新。函数split_part()更适合您的查询:

select split_part(post_id, '_', 2) as post_id
from abc
where split_part(post_id, '_', 2) = any('{912876412107255, 912883258773237}');

答案 1 :(得分:0)

未经测试(来自我的手机):

SELECT kmkid, element_id
    FROM (SELECT (regexp_split_to_array(element_id, '_'))[2] as kmkid, element_id FROM ABC)
    WHERE kmkid IN ('912876412107255', '912876412107255');

答案 2 :(得分:0)

快速说明一下,这里的问题是你在同一个字段中序列化了两个值。这是不好的。如果您正在执行此操作,因为这些值不同。

你应该做的是将它们分开,或者如果它们是列表,则将它们存储为数组。

ALTER TABLE abc
  ALTER COLUMN post_Id
  SET DATA TYPE numeric[] USING ( string_to_array(post_Id, '_')::numeric[] );

现在,如果任何一个字段相等,你可以直接查询foo

SELECT * FROM abc
WHERE post_id @> ARRAY[912876412107255::numeric];

或者如果其中一个是

SELECT * FROM abc
WHERE post_id[2] = 912876412107255::numeric;

答案 3 :(得分:-1)

好的,我刚刚找到答案:

select (regexp_split_to_array(element_id, '_'))[2] as element_id from ABC where element_id similar to '%(912876412107255|912883258773237)%';
     element_id     
-----------------
 912876412107255
 912883258773237
(2 rows)