2016-06-28 4 views
5

Мне было интересно, можно ли сделать запрос, используя предложение IN, где параметры внутри него являются предложениями LIKE, например, у меня есть мой существующий SQL, который возвращает те же результаты, что и я, кругом о том, как это сделать.PostgreSQL WHERE IN LIKE query

SELECT * 
FROM pg_stat_activity 
WHERE application_name NOT LIKE '%psql%' 
AND (current_timestamp - state_change) > INTERVAL '30 minutes' 
AND state IN (
    SELECT state 
    FROM pg_stat_activity 
    WHERE state LIKE '%idle%' 
    OR state LIKE '%disabled%' 
) 

Есть ли способ, чтобы заменить что-то вдоль линий

SELECT * 
FROM pg_stat_activity 
WHERE application_name NOT LIKE '%psql%' 
AND (current_timestamp - state_change) > INTERVAL '30 minutes' 
AND state IN ('%idle%', '%disabled%') 

ответ

3

Используйте похожие на вместо LIKE

AND state SIMILAR TO '%(idle|disabled)%'

https://www.postgresql.org/docs/9.0/static/functions-matching.html

+0

Этот ответ решил мою проблему, но если аналогичный TO может сделать это с помощью уникальных опций и нескольких вариантов, то зачем кому-либо когда-либо использовать LIKE? – Trent

+0

@Trent «ПОДОБНОЕ TO» использует регулярное выражение под капотом. Поэтому я ожидаю, что он может работать медленнее, чем 'LIKE'. Но я не думаю, что это ваш случай. – Arsen

3

Фактически использование something IN (<value list>) похож на something = any(array[<value list>]) в PostgreSQL:

postgres=# explain select 1 where 'a' in ('a','b','c'); 
         QUERY PLAN       
---------------------------------------------------------- 
Result (cost=0.00..0.01 rows=1 width=0) 
    One-Time Filter: ('a'::text = ANY ('{a,b,c}'::text[])) 
(2 rows) 

К счастью, мы можем использовать like или даже ilike вместо =:

select 1 where 'aa' ilike any(array['%A%','%B%','%C%']); 
?column? 
---------- 
     1 
(1 row) 

Так что в вашем случае это может быть

... state LIKE ANY(ARRAY['%idle%', '%disabled%']) 

И дополнительный a dvantage: его можно передать как параметр из клиентского приложения.

+0

Ха, я печатаю слишком медленно. –

+0

@CraigRinger И кажется, что мы оба проиграли: o) – Abelisto

2

x IN (a, b) может считаться сокращенным для x = ANY (ARRAY[a,b]). Аналогичным образом, x IN (SELECT ...) и x = ANY (SELECT ...).

= может быть фактически заменен любым двоичным оператором. Таким образом, вы можете использовать:

SELECT ... WHERE x LIKE ANY (SELECT ...)