This page contains a collection of examples of SQL queries you can write with the Laminar SQL Editor. For the reference of the table schemas and Laminar-specific syntax, see the reference page.

Basic queries

Counting spans in the last 3 days

SELECT
    count(span_id) as span_count
FROM spans
WHERE start_time BETWEEN now() - INTERVAL '3 days' AND now()

Counting spans by name

SELECT
    name,
    count(span_id) as span_count
FROM spans
GROUP BY name
ORDER BY span_count DESC
LIMIT 10

Viewing spans of a specific evaluation run

SELECT
    name,
    input,
    output
FROM
    spans
WHERE
    -- this applies the necessary joins behind the scenes
    evaluation_name = 'the-evaluation-name'
This query will return the input and output of the spans of the evaluation run with the name the-evaluation-name. It is useful to filter by span type in this query to filter either the executor (forward pass) or the evaluator spans.

Filtering spans by type

SELECT
    name,
    input,
    output
FROM
    spans
WHERE
    span_type = 'LLM'
Available span types:
  • DEFAULT - most of the spans fall into this category
  • LLM - a manual or automatically traced LLM call
  • EVALUATION - a span that represents an evaluation run. One datapoint is evaluated by one evaluation run.
  • EXECUTOR - a span that represents an executor run. One datapoint is evaluated by one executor run.
  • EVALUATOR - a span that represents an evaluator run. One datapoint may have multiple evaluator spans.
  • TOOL - a span that represents a tool call.

Filtering spans by span path

Span path is the hierarchical path of the span. For example, if your code looks like this:
@observe
def outer():
    @observe
    def inner():
        return "Hello, world!"
    return inner()
Then the span path of the inner function will be ["outer", "inner"]. Span path is stored as a JSONB array inside the attributes column’s values. However, Laminar SQL provides syntactic sugar for you to query, filter, order, or group by span path items joined by a dot.
SELECT
    name,
    input,
    output
FROM spans WHERE path = 'outer.inner'

Tags

Tags are returned as an SQL text[] array. Tags are stored outside of the spans table, but Laminar SQL Editor joins them to the spans table by span_id and aggregates them as an array. SQL array syntax is not exactly trivial, so here are a few examples:

Filtering by a presence of a tag

SELECT 
    name,
    input,
    output,
    tags
FROM spans
-- this applies the necessary joins behind the scenes
WHERE 'my_tag' = ANY(tags)

Filtering by multiple tags

SELECT
    name,
    input,
    output,
    tags
FROM spans
-- the `@>` operator is the SQL array containment operator
WHERE tags @> ARRAY['tag1', 'tag2']
-- this is equivalent to
-- WHERE 'tag1' = ANY(tags) AND 'tag2' = ANY(tags)
-- and equivalent to
-- WHERE tags @> '{tag1, tag2}'::text[]

Filtering by any of the tags

SELECT
    name,
    input,
    output,
    tags
FROM spans
WHERE tags && ARRAY['tag1', 'tag2']
-- this is equivalent to
-- WHERE 'tag1' = ANY(tags) OR 'tag2' = ANY(tags)

Filtering based on the number of tags

This query will return all spans with more than 2 tags.
SELECT
    name,
    input,
    output,
    tags
FROM spans
-- second argument of `array_length` is the dimension of the array
-- in this case, it is 1 because `tags` is a 1-dimensional array
WHERE array_length(tags, 1) > 2

Filtering spans by evaluator scores

SELECT
    name,
    input,
    output,
    evaluator_scores.my_score
FROM spans
-- this applies the necessary joins behind the scenes
WHERE evaluator_scores.my_score > 0.5

Filtering evaluation results by scores

SELECT
    id,
    index,
    duration,
    evaluation_scores."My Score"
FROM evaluation_results
WHERE evaluation_scores."My Score" >= 0

Advanced examples

Digging into the LLM span attributes and type casting

SELECT 
    name,
    input,
    output,
    attributes->>'gen_ai.response.model' response_model,
    (attributes->>'gen_ai.usage.input_tokens')::int8 input_tokens,
    (attributes->>'gen_ai.usage.output_tokens')::int8 output_tokens,
    (attributes->>'gen_ai.usage.input_cost')::float8 input_cost,
    (attributes->>'gen_ai.usage.output_cost')::float8 output_cost
FROM spans
WHERE span_type = 'LLM'