File size: 7,451 Bytes
e535652
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
---
title: SQL Templating
sidebar_position: 4
description: Use Jinja templates in SQL Lab and virtual datasets to create dynamic queries
keywords: [sql templating, jinja, sql lab, virtual datasets, dynamic queries]
---

{/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/}

# SQL Templating

Superset supports [Jinja templating](https://jinja.palletsprojects.com/) in SQL Lab queries and virtual datasets. This allows you to write dynamic SQL that responds to filters, user context, and URL parameters.

:::note
SQL templating must be enabled by your administrator via the `ENABLE_TEMPLATE_PROCESSING` feature flag.
For advanced configuration options, see the [SQL Templating Configuration Guide](/admin-docs/configuration/sql-templating).
:::

## Using Jinja in Calculated Columns

Jinja template macros are available in calculated column expressions in the dataset editor — not just in SQL Lab queries and virtual datasets. This allows column expressions to reference the current user or dynamic context.

**Example: User-scoped calculated column**

```sql
CASE WHEN sales_rep = '{{ current_username() }}' THEN amount ELSE 0 END
```

**Example: Conditional display based on role**

Because `current_user_roles()` returns a Python list, test role membership with a Jinja
conditional at template time rather than matching against the list's string representation:

```sql
{% if 'Finance' in current_user_roles() %}revenue{% else %}NULL{% endif %} AS finance_revenue
```

:::note
The `ENABLE_TEMPLATE_PROCESSING` feature flag must be enabled by your administrator for Jinja in calculated columns to work.
:::

## Basic Usage

Jinja templates use double curly braces `{{ }}` for expressions and `{% %}` for logic blocks.

### Using Parameters

You can define parameters in SQL Lab via the **Parameters** menu as JSON:

```json
{
  "my_table": "sales",
  "start_date": "2024-01-01"
}
```

Then reference them in your query:

```sql
SELECT *
FROM {{ my_table }}
WHERE order_date >= '{{ start_date }}'
```

### Conditional Logic

Use Jinja's logic blocks for conditional SQL:

```sql
SELECT *
FROM orders
WHERE 1 = 1
{% if start_date %}
  AND order_date >= '{{ start_date }}'
{% endif %}
{% if end_date %}
  AND order_date < '{{ end_date }}'
{% endif %}
```

## Available Macros

Superset provides built-in macros for common use cases.

### User Context

| Macro                        | Description                             |
| ---------------------------- | --------------------------------------- |
| `{{ current_username() }}`   | Returns the logged-in user's username   |
| `{{ current_user_id() }}`    | Returns the logged-in user's account ID |
| `{{ current_user_email() }}` | Returns the logged-in user's email      |
| `{{ current_user_roles() }}` | Returns an array of the user's roles    |

**Example: Row-level filtering by user**

```sql
SELECT *
FROM sales_data
WHERE sales_rep = '{{ current_username() }}'
```

**Example: Role-based access**

```sql
SELECT *
FROM users
WHERE role IN {{ current_user_roles()|where_in }}
```

### Filter Values

Access dashboard and chart filter values in your queries:

| Macro                           | Description                     |
| ------------------------------- | ------------------------------- |
| `{{ filter_values('column') }}` | Returns filter values as a list |
| `{{ get_filters('column') }}`   | Returns filters with operators  |

**Example: Using filter values**

```sql
SELECT product, SUM(revenue) as total
FROM sales
WHERE region IN {{ filter_values('region')|where_in }}
GROUP BY product
```

The `where_in` filter converts the list to SQL format: `('value1', 'value2', 'value3')`

### Time Filters

For charts with time range filters:

| Macro                             | Description                                        |
| --------------------------------- | -------------------------------------------------- |
| `{{ get_time_filter('column') }}` | Returns time filter with `from_expr` and `to_expr` |

**Example: Time-filtered virtual dataset**

```sql
{% set time_filter = get_time_filter("order_date", default="Last 7 days") %}
SELECT *
FROM orders
WHERE order_date >= {{ time_filter.from_expr }}
  AND order_date < {{ time_filter.to_expr }}
```

### URL Parameters

Pass custom values via URL query strings:

```sql
SELECT *
FROM orders
WHERE country = '{{ url_param('country') }}'
```

Access via: `superset.example.com/sqllab?country=US`

### Reusing Dataset Definitions

Query existing datasets by ID:

```sql
-- Query a dataset (ID 42) as a table
SELECT * FROM {{ dataset(42) }} LIMIT 100

-- Include computed metrics
SELECT * FROM {{ dataset(42, include_metrics=True) }}
```

Reuse metric definitions across queries:

```sql
SELECT
  category,
  {{ metric('total_revenue') }} as revenue
FROM sales
GROUP BY category
```

## Testing Templates in SQL Lab

Some variables like `from_dttm` and `filter_values()` only work when filters are applied from dashboards or charts. To test in SQL Lab:

**Option 1: Use defaults**

```sql
SELECT *
FROM orders
WHERE date >= '{{ from_dttm | default("2024-01-01", true) }}'
```

**Option 2: Set test parameters**

Add to the Parameters menu:

```json
{
  "_filters": [{ "col": "region", "op": "IN", "val": ["US", "EU"] }]
}
```

**Option 3: Use `{% set %}`**

```sql
{% set start_date = "2024-01-01" %}
SELECT * FROM orders WHERE date >= '{{ start_date }}'
```

## Common Patterns

### Dynamic Table Selection

```sql
{% set table_name = url_param('table') or 'default_table' %}
SELECT * FROM {{ table_name }}
```

### User-Specific Data Access

```sql
SELECT *
FROM sensitive_data
WHERE department IN (
  SELECT department
  FROM user_permissions
  WHERE username = '{{ current_username() }}'
)
```

### Time-Based Partitioning

```sql
{% set time_filter = get_time_filter("event_date", remove_filter=True) %}
SELECT *
FROM events
WHERE event_date >= {{ time_filter.from_expr }}
  AND event_date < {{ time_filter.to_expr }}
```

Using `remove_filter=True` applies the filter in the inner query for better performance.

## Tips

- Use `|where_in` filter to convert lists to SQL `IN` clauses
- Use `|tojson` to serialize arrays as JSON strings
- Test queries with explicit parameter values before relying on filter context
- For complex templating needs, ask your administrator about custom Jinja macros
- **Format SQL is Jinja-aware**: The "Format SQL" button in SQL Lab correctly preserves `{{ }}` and `{% %}` template syntax and applies your selected database's SQL dialect when formatting.

:::resources

- [Admin Guide: SQL Templating Configuration](/admin-docs/configuration/sql-templating)
- [Blog: Intro to Jinja Templating in Apache Superset](https://preset.io/blog/intro-jinja-templating-apache-superset/)
  :::