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'

Filtering spans by tags

SELECT 
    name,
    input,
    output
FROM spans
-- this applies the necessary joins behind the scenes
WHERE tag = 'my_tag'

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'