2016-06-28 17 views
5

Mi chiedevo se è possibile eseguire una query utilizzando la clausola IN in cui le opzioni al suo interno sono clausole LIKE, ad esempio ho il mio SQL esistente che restituisce gli stessi risultati che intendo sembra proprio come un giro sul modo di farlo.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%' 
) 

C'è un modo per sostituire con qualcosa sulla falsariga di

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

risposta

3

Usa SIMILE A invece di COME

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

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

+0

Questa risposta ha risolto il mio problema ma se SIMILE TO può farlo con opzioni singolari e opzioni multiple, allora perché qualcuno dovrebbe usare LIKE? – Trent

+0

@Trent 'SIMILAR TO' usa regex sotto il cofano. Quindi mi aspetto che funzioni più lentamente di 'LIKE'. Ma non penso che sia il tuo caso – Arsen

3

realtà utilizzando something IN (<value list>) è simile al something = any(array[<value list>]) in 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) 

Per fortuna possiamo utilizzare like o addirittura ilike invece di =:

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

Quindi nel tuo caso potrebbe essere

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

E l'ulteriore a dvantage: può essere passato come parametro dall'applicazione client.

+0

Ha, digito troppo lento. –

+0

@CraigRinger E sembra che entrambi abbiamo perso: o) – Abelisto

2

x IN (a, b) può essere considerato stenografia per x = ANY (ARRAY[a,b]). Allo stesso modo, x IN (SELECT ...) e x = ANY (SELECT ...).

Il = può essere effettivamente sostituito da qualsiasi operatore binario. Quindi, è possibile utilizzare:

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