From data-analysis-tools
Use when the user needs to filter data — whether in a perspective query, a metric aggregation, or an attribute expression. Covers filter syntax, date handling, and best practices.
How this skill is triggered — by the user, by Claude, or both
Slash command
/data-analysis-tools:filteringThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Filtering restricts which rows contribute to a result. The same expression language applies across three contexts in Honeydew:
Filtering restricts which rows contribute to a result. The same expression language applies across three contexts in Honeydew:
| Context | Where it appears | When it runs |
|---|---|---|
| Perspective query | filters: block in YAML perspective | Pre-aggregation |
| Metric aggregation | FILTER (WHERE ...) on an aggregation | During aggregation |
| Attribute expression | CASE WHEN ... END in attribute SQL | Per-row evaluation |
| Metric value filter | Metric expression in filters: param | Post-aggregation |
entity.field = 'value'
entity.field > 100
entity.field >= 3 AND entity.field < 10
Operators: =, <, >, >=, <=, !=
You can compare an attribute to a constant or to another attribute. Cast mismatching types when comparing (e.g., entity.field::DATE).
entity.field = 'exact value'
entity.field IN ('val1', 'val2', 'val3')
entity.field ILIKE '%keyword%'
ILIKE is case-insensitive pattern matching (% = any characters, _ = one character)Use SEARCH when you don't know exact values and need to find possible matches.
-- Single search — always use SEARCH_MODE => 'AND'
SEARCH(entity.field, 'search terms', SEARCH_MODE => 'AND')
-- Multiple alternatives — use OR between SEARCH calls
SEARCH(entity.field, 'term1', SEARCH_MODE => 'AND') OR SEARCH(entity.field, 'term2', SEARCH_MODE => 'AND')
Always use SEARCH_MODE => 'AND'.
entity.field IS NULL
entity.field IS NOT NULL
entity.flag = true
entity.flag = false
YEAR(entity.date_field) = 2023
entity.date_field >= '2024-01-01'
entity.date_field BETWEEN '2024-02-05'::DATE AND '2024-02-10'::DATE
entity.price > 50 AND entity.room_type = 'Private room'
entity.status = 'active' OR entity.status = 'pending'
Use AND / OR to combine conditions. Use parentheses to control precedence.
Cast when types don't match:
entity.string_field::DATE
entity.number_field::VARCHAR
'2024-01-01'::DATE
DATE('2024-01-01')
In a YAML perspective, the filters: block applies row-level filters before aggregation:
type: perspective
name: entire_home_stats
attributes:
- detailed_listings.neighbourhood_cleansed
metrics:
- detailed_listings.count
filters:
- detailed_listings.room_type = 'Entire home/apt'
- detailed_listings.price > 50
Each entry in the filters: list is ANDed together.
Inside a metric's SQL, use FILTER (WHERE ...) to restrict which rows feed the aggregation:
SUM(orders.price) FILTER (WHERE orders.color = 'red')
COUNT(orders.id) FILTER (WHERE orders.status = 'completed')
Use FILTER (WHERE ...), not CASE WHEN, for filtered aggregations in metrics.
In attribute SQL, use CASE WHEN for conditional per-row logic:
CASE
WHEN orders.amount > 1000 THEN 'high'
WHEN orders.amount > 100 THEN 'medium'
ELSE 'low'
END
You can filter on aggregated metric values — the equivalent of SQL's HAVING clause. Use the metric expression (named or ad-hoc) in the filters parameter of a structured query. These filters are applied after aggregation.
This works with both named metrics (e.g., entity.metric_name > 10) and ad-hoc aggregations (e.g., COUNT(entity.field) > 1).
For examples — including duplicate detection, minimum group size, and revenue thresholds — see
examples.md.
| Function | Use |
|---|---|
CURRENT_DATE | Reference today |
DATE_TRUNC | Get boundaries: DATE_TRUNC(month, CURRENT_DATE()) |
INTERVAL | Relative time: CURRENT_DATE() - INTERVAL '1 month' |
| Cast strings | DATE('2024-01-01') or '2024-01-01'::DATE |
DATE_TRUNC(month, order.order_date) = DATE_TRUNC(month, CURRENT_DATE() - INTERVAL '1 month')
Do NOT use interval calculation when asked about specific dates (e.g., "November 2024"). Use explicit date values instead.
SEARCH when values are unknown — avoids hard-coding exact stringsILIKE for pattern matching — case-insensitive, good for partial matchesFILTER (WHERE ...) in metrics, not CASE WHEN — cleaner, standard SQLCASE WHEN in attributes — for per-row conditional logicIN (...) over multiple OR — cleaner for known value listsCURRENT_DATE, DATE_TRUNC, INTERVALnpx claudepluginhub honeydew-ai/honeydew-ai-coding-agents-pluginsExplains Honeydew filter syntax for structured queries, metric aggregations, attribute expressions, and metric value filters. Covers comparisons, strings, dates, Snowflake full-text search, and best practices.
Runs queries against Omni Analytics' semantic layer via the Omni CLI, interprets results, and chains queries for multi-step analysis. Useful for extracting data from Omni dashboards or workbooks programmatically.
Automates Looker dashboard creation: add elements, filters, and configure queries. Useful for data discovery and BI workflows.