Reputation: 97
I want to change the condition on the array column call_type
in below query so it excludes everything that has 'visit_occurred'.
How do I work with that array part?
select staff_id,
COUNT(event_id) as offered
from call_logs as logs
where visit_offered
and contact_date between now() - interval '1 weeks' and now()
and provider_type = 'Contractor'
and contact_with != 'company_staff'
and direction = 'outbound'
and outcome = 'Successful'
and call_type && array ['Schedule','schedule_visit']
group by staff_id;
Upvotes: 2
Views: 1901
Reputation: 659207
To simply match array elements as a whole use the ARRAY contains operator @>
, negated:
AND NOT call_type @> '{schedule_visit}'::text[]
Note the array wrapper. The cast to text[]
is typically not needed, but can help to avoid ambiguity.
If the column can be NULL
, and you don't want to exclude such rows:
AND (call_type @> '{schedule_visit}'::text[]) IS NOT TRUE
Can be supported with an index:
Pattern matching is more sophisticated. Use a NOT EXISTS
expression:
AND NOT EXISTS (
SELECT FROM unnest(logs.call_type) call
WHERE call ILIKE '%visit_occurred%' -- case insensitive?
)
No index support for this. Related answer for a JSON array (same principle):
An alternative would be normalizing your array column as a separate n:1 table.
Upvotes: 4