Filtering
functionalQuick-filter from any cell, pause conditions, type filter expressions with relative dates, and save filters per table.
Every result grid can be narrowed without touching the query. Right-click a cell for a one-click quick filter, stack conditions in the filter builder, type an expression when the keyboard is faster, and save the setups you reach for every week. Filters re-shape what the grid shows; your SQL stays as written until you deliberately push a filter into it with Apply to Query.
Quick filters from a cell
Right-click any data cell and the Filter: entries are right there: = value, <> value, contains value, IS NULL, and IS NOT NULL. Pick one and the grid filters immediately - no dialog round-trip, no SQL rewrite. The filter builder opens with the new condition added, so what is filtering the grid is always visible and adjustable. A NULL cell offers just the two null tests, which are the only sensible questions to ask of it.
A quick filter always narrows: it is AND-ed onto whatever is already filtering the grid, even when the builder holds an OR group, and it leaves the header's value checklists in place. Number and date cells compare by value (=, <>); contains and text comparisons match the text the grid shows, thousands separators included, so the row you clicked always stays. Text comparisons in the grid ignore case - = Active also keeps active - while Apply to Query leaves case to the column's collation.

The filter builder, and pausing a condition
Filter Rows… (also on the right-click menu) is the full builder:
conditions across any columns, text and number operators, AND/OR groups nested as
deep as you need, and Apply to Query when the predicate belongs in
the SQL instead. Apply to Query writes dialect-correct literals - dates become
'20260928' on SQL Server, DATE '2026-09-28' on Oracle,
PostgreSQL, and MySQL - and numbers keep every digit you typed.
Every condition row has a checkbox - uncheck it to pause the condition without
deleting it. Disabled conditions stay in the list (and in saved filters) but are
skipped everywhere: the grid, the client-side predicate, and the generated WHERE
clause. The checkbox is live: the grid re-filters the moment you tick or untick
it. Close the builder and reopen it later and the paused conditions, OR groups,
and date comparisons are still there, as long as the grid is still filtered by
them - Clear Filters or a header-menu filter change starts the
builder fresh from what the grid actually shows. When you are tuning a
five-condition stack, that is the difference between an experiment and a rewrite.
The builder is also in the command palette as Results: Filter Rows….

Filter expressions
The expression field at the top of the builder accepts a typed mini-language and
lowers it to the same conditions the builder edits by hand. Comma means
OR, space means AND, and AND binds tighter, so
status = active, created >= LAST WEEK reads exactly as it looks.
Leaving out the column name reuses the previous one:
status = active, pending is active or pending.
| You type | Meaning |
|---|---|
status = active (or just status active) | equality; != and <> negate |
qty >=5 <=10 | a range, as two AND-ed conditions |
name ^jo, name $son, name ~ann, name !~ann | starts with, ends with, contains, does not contain |
deleted = NULL, deleted = NOT NULL | null tests (case-insensitive) |
created = 2026-09 | a partial date: all of September 2026; 2026 is the whole year |
created >= LAST WEEK | relative dates on date columns: TODAY, YESTERDAY, THIS/LAST WEEK, THIS/LAST MONTH, THIS/LAST YEAR |
Day equality is inclusive (created = 2026-09-28 matches any time that
day), weeks start on Monday, and keywords ignore case. Dates take four-digit years.
TODAY and the other relative dates follow the time zone the grid shows
datetimes in - UTC unless you changed the date display setting - so
today is the day you see in the grid. The keywords are keywords only on
date columns: on a text column status = today looks for the word
today. Values with spaces or any of = ! < > ^ $ ~ need
quotes (status = 'in progress', url = 'a=b'), as do column
names ([my col] = x). Large numbers compare exactly:
id = 1234567890123456789 matches that id and no neighbour. Press Enter
or Apply expression;
applying replaces the current conditions. An invalid expression shows a red hint
that says what is wrong (unknown column, 'abc' is not a number,
operator '<' needs a number or date column) and changes nothing.

!^, !$) are not supported - use !~ or !=. Date comparisons in the grid read the text the grid shows, so they need a date column displayed ISO-style (2026-09-28); on a column with another date format the builder shows a warning, because the comparison would match nothing - change the column's date format or use Apply to Query. Date comparisons filter through the client-side predicate, so they apply to the rows the grid holds.Saved filters, with a per-table default
When a filter stack is worth keeping, type a name and Save. Saved
filters belong to the connection profile that ran the query (its server, port,
engine, and database), and single-table statements - including a table browse -
share one scope per table; a three-part name such as sales.dbo.orders
counts as that database's table. Each condition remembers its column by name, so a
default set up while browsing SELECT * lands on the right columns
whatever projection, ordering, or formatting you return with. When the result lacks
a column a condition needs, that condition is skipped and a note above the grid
names it. Other statements are scoped to their own text and result-set position.
The dropdown lists them with Apply, Rename, and
Delete; Toggle default marks the one that applies
itself automatically when a fresh result for that table opens. It applies once per
result: clearing or changing the filter sticks, even when the grid is rebuilt for a
staged edit. Re-saving an existing name replaces it and keeps its default status.
Multi-statement batches keep saved filters per result set but never apply a default by themselves - which table a batch's third result came from is not something the SQL pins down - so Toggle default is hidden there. Saved filters are written atomically; if the file on disk cannot be read, the builder says so and leaves it untouched instead of saving over it.
Save right after applying an expression and the expression text is stored with
the filter. Relative dates are resolved again every time the filter is applied,
so a saved created >= LAST WEEK still means last week next month.
Adjust the conditions by hand before saving and only the conditions are kept,
with their dates fixed. If a saved expression stops parsing - a column was
renamed - the stored conditions are used instead.

Top values
A column header's Top Values… opens the column's most common values with their counts - up to thirty, ranked by frequency (ties in text order), with a NULL row first when nulls exist. Clicking a value filters the column to it (NULL applies IS NULL). It is the fastest way to answer “what is actually in this column?” and then act on the answer. Counts cover the rows currently visible, after filtering - the same rows the copy actions below read. A result too large to hold in memory is counted from its first 100,000 rows, read from disk in the background: the window opens at once and says it is counting, then its header says how many of how many rows it counted. Run the query again and an open Top Values window stops filtering and asks to be reopened, because its counts describe the old result.

Copying distinct values
Copy Distinct Values on a column header puts every distinct
value on the clipboard as plain lines, in first-seen order - ready for a paste
into a ticket, a diff, or another tool. Copy Top 25 Values (Most Frequent
First) copies just the 25 most common values, ranked by count (ties keep
first-seen order). NULL appears as NULL in both. Both copy the stored
values (with masking applied), not display formatting such as thousands
separators. They complement Copy as SQL IN list (distinct), which wraps
the same set in IN (…) for a WHERE clause. All of them copy the rows
currently visible after sorting and filtering. When a filter hides every row, or
the result has no rows, Copy Distinct and Copy Top 25 copy nothing and Messages
says so; on a result too large to hold in memory they read the first 100,000 rows
in the background - a note above the grid says what is being counted meanwhile -
copy when the read finishes, and Messages says how many of how many were read.
Starting another copy replaces one still reading, and running the query again
cancels it. Copy Column Profile as Markdown reads a large result the same way.