2017-04-13 27 views
1

我想要獲取值的哪些部分的ID是在一個定義的列表中。比方說,我們有一個稱爲表ABCPostgreSQL字符串的一部分是在一個數組中

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 
+0

where子句? (不認爲這是允許的) 此外,爲什麼只有1個元素時,將選定的表達式放入數組中。 –

+0

@JoeLove:這是不允許的。這就是爲什麼戈德里克失敗的原因。 – kmkaplan

+1

是的,謝謝。我想通了,並立即發佈答案 – Godric

回答

-1

OK,我剛剛找到了答案:

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) 
+0

添加'_'並刪除尾部的'%'以獲得更少的虛假匹配。如果某些'element_id'碰巧是你想要的前綴,你仍然可以得到一些。總結它的一個醜陋的解決方案。 – kmkaplan

+1

避免使用正則表達式函數。簡單的字符串操作功能更便宜(更快)。 – klin

+0

也是整個SIMILAR TO是愚蠢的。它總是比正則表達式慢。而且,你知道整個ID是什麼。那麼爲什麼在將它分開後使用'%'? –

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

使用比正則表達式功能便宜得多的功能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}'); 
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; 
相關問題