Download as pdf or txt
Download as pdf or txt
You are on page 1of 20

Upcoming Tour of Metabase advanced Register Now ×

Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Custom expressions to create


Installation Custom expressions filters, metrics, and custom
columns
Custom expressions are like formulas in spreadsheet software like Excel, Google Sheets, and LibreOffice Calc. They are the power tools in the notebook editor of the
Databases
query builder that allow you to ask more complicated questions. Types of expressions

Questions Basic mathematical operators


You can also skip to the complete list of expressions.
Conditional operators
Questions overview
Referencing other columns
Asking questions Custom expressions to create filters, metrics, and custom columns
Referencing Segments and Metrics
Visualizing data To use custom expression, create a Custom Column (where the custom expression is used as a Field Formula to calculate values for the new column), or click on Filter
Filter expressions and conditionals
or Summarize and select Custom Expression.
Custom expressions
Working with dates in filter
List of expressions When using the query builder, you can use expressions to create new: expressions

Joining data Custom columns. You could use = [Subtotal] / [Quantity] to create a new column, which you could name “Item price”. List of expressions

The SQL editor Filters. The expression = contains([comment], "Metabase") would filter for rows where the comment field contained the word “Metabase”.
SQL parameters Summaries. Also known as metrics or aggregations. = Share([Total] > 50) would return the percentage of orders with totals greater than 50 dollars.
Referencing models and saved
questions This page covers the basics of expressions. You can check out a full list of expressions in Metabase, or walk through a tutorial that shows you how you can use
custom expressions in the notebook editor.
SQL snippets

SQL snippet folder permissions

Sharing answers Types of expressions


Alerts There are two basic types of expressions, Aggregations and Functions. Check out a full list of expressions.
Public sharing
Aggregations
Exporting data
Aggregations take values from multiple rows to perform a calculation, such as finding the average value from all values in a column. Aggregations functions can only
Dashboards be used in the Summarize section of the notebook editor, because aggregations use values from all rows for that column. So while you could create a custom column
with the formula [Subtotal] + [Tax] , you could not write Sum([Subtotal] + [Tax]) , unless you were creating a custom metric expression (that would add up all
Data modeling the subtotals and taxes together).

Actions Functions
Functions, by contrast, do something to each value in a column, like searching for a word in each value ( contains ), rounding each value up to the nearest integer (the
Organization ceil function), and so on.

People

Permissions
Basic mathematical operators
Use + , - , * (multiply), / (divide) on numeric columns with numeric values, like integers, floats, and double. You can use parentheses, ( and ) , to group parts of your
Embedding expression.

Configuration For example, you could create a new column that calculates the difference between the total and subtotal of a order: = [Total] - [Subtotal] .

To do math on timestamp columns, you can use Date functions like dateDiff.
Tools

Cloud
Conditional operators
Metabase API
AND , OR , NOT , > , >= (greater than or equal to), < , <= (less than or equal to), = , != (not equal to).

Troubleshooting For example, you could create a filter for customers from California or Vermont: = [State] = "CA" OR [State] = "VT" .

Developer guide

Referencing other columns


Paid features
You can refer to columns in the current table, or to columns that are linked via a foreign key relationship. Column names should be included inside of square brackets,
like this: [Name of Column] . Columns in connected tables can be referred to like this: [ConnectedTableName.Column] .

Referencing Segments and Metrics


You can refer to saved Segments or Metrics that are present in the currently selected table. You write these out the same as with columns, like this: [Valid User
Sessions] .

Filter expressions and conditionals


Some things to keep in mind about filter expressions and conditionals:

Filter expressions are different in that they must return a Boolean value (something that’s either true or false). For example, you could write [Subtotal] + [Tax]
< 100 . Metabase would look at each row, add its subtotal and tax, the check if that sum is greater than 100. If it is, the statement evaluates as true, and Metabase
will include the row in the result. If instead you were to (incorrectly) write [Subtotal] + [Tax] , Metabase wouldn’t know what to do, as that expression doesn’t
evaluate to true or false.

You can use functions inside of the conditional portion of the CountIf and SumIf aggregations, like so: CountIf( round([Subtotal]) > 100 OR floor([Tax])
< 10 ) .

Working with dates in filter expressions


If you want to work with dates in your filter expressions, the dates need to follow the format, "YYYY-MM-DD" — i.e., four characters for the year, two for the month,
and two for the day, enclosed in quotes " and separated by dashes - .

Example:

between([Created At], "2020-01-01", "2020-03-31") OR [Received At] > "2019-12-25"

This expression would return rows where Created At is between January 1, 2020 and March 31, 2020, or where Received At is after December 25, 2019.

List of expressions
See a full list of expressions.

For a tutorial on expressions, see Custom expressions in the query builder.

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
© Metabase 2024
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Aggregations
Installation List of expressions
Functions
For an introduction to expressions, check out the overview of custom expressions.
Databases Logical functions
Aggregations
Questions Math functions
Average
String functions
Questions overview Count
Date functions
Asking questions CountIf
Limitations
CumulativeCount
Visualizing data
CumulativeSum
Custom expressions
Distinct
List of expressions
Max
Joining data
Median
The SQL editor
Min
SQL parameters
Percentile
Referencing models and saved
questions Share
SQL snippets StandardDeviation
SQL snippet folder permissions Sum

Sharing answers SumIf

Alerts Variance

Public sharing Functions

Exporting data Logical functions

between
Dashboards
case

Data modeling coalesce

isnull
Actions
notnull
Organization Math functions

abs
People
ceil
Permissions exp

floor
Embedding
log
Configuration power

round
Tools
sqrt
Cloud String functions

concat
Metabase API
contains
Troubleshooting
doesNotContain

Developer guide endsWith

isempty
Paid features
ltrim

length

lower

notempty

regexextract

replace

rtrim

startsWith

substring

trim

upper

Date functions

convertTimezone

datetimeAdd

datetimeDiff

datetimeSubtract

day

hour

interval

minute

month

now

quarter

relativeDateTime

second

week

weekday

year

Database limitations

Aggregations
Aggregation expressions take into account all values in a field. They can only be used in the Summarize section of the query builder.

Average
Returns the average of the values in the column.

Syntax: Average(column)

Example: Average([Quantity]) would return the mean for the Quantity field.

Count
Returns the count of rows (also known as records) in the selected data.

Syntax: Count

Example: Count If a table or result returns 10 rows, Count will return 10 .

CountIf
Only counts rows where the condition is true.

Syntax: CountIf(condition) .

Example: CountIf([Subtotal] > 100) would return the number of rows where the subtotal were greater than 100.

CumulativeCount
The additive total of rows across a breakout.

Syntax: CumulativeCount .

Example: CumulativeCount .

CumulativeSum
The rolling sum of a column across a breakout.

Syntax: CumulativeSum(column) .

Example: CumulativeSum([Subtotal]) .

Related: Sum and SumIf.

Distinct
The number of distinct values in this column.

Syntax: Distinct(column) .

Distinct([Last Name]) . Returns the count of unique last names in the column. Duplicates (of the last name “Smith” for example) are not counted.

Max
Returns the largest value found in the column.

Syntax: Max(column) .

Example: Max([Age]) would return the oldest age found across all values in the Age column.

Related: Min, Average, Median.

Median
Returns the median value of the specified column.

Syntax: Median(column) .

Example: Median([Age]) would find the midpoint age where half of the ages are older, and half of the ages are younger.

Databases that don’t support median : SQLite, Vertica, SQL server, MySQL. Presto only provides approximate results.

Related: Min, Max, Average.

Min
Returns the smallest value found in the column.

Syntax: Min(column) .

Example: Min([Salary]) would find the lowest salary among all salaries in the Salary column.

Related: Max, Median, Average.

Percentile
Returns the value of the column at the percentile value.

Syntax: Percentile(column, percentile-value)

Example: Percentile([Score], 0.9) would return the value at the 90th percentile for all values in that column.

Databases that don’t support percentile : H2, MySQL, SQL Server, SQLite, Vertica. Presto only provides approximate results.

Share
Returns the percent of rows in the data that match the condition, as a decimal.

Syntax: Share(condition)

Example: Share([Color] = "Blue") would return the number of rows with the Color field set to Blue , divided by the total number of rows.

StandardDeviation
Calculates the standard deviation of the column, which is a measure of the variation in a set of values. Low standard deviation indicates values cluster around the
mean, whereas a high standard deviation means the values are spread out over a wide range.

Syntax: StandardDeviation(column)

Example: StandardDeviation([Population]) would return the SD for the values in the Population column.

Sum
Adds up all the values of the column.

Syntax: Sum(column)

Example: Sum([Subtotal]) would add up all the values in the Subtotal column.

SumIf
Sums up the specified column only for rows where the condition is true.

Syntax: SumIf(column, condition) .

Example: SumIf([Subtotal], [Order Status] = "Valid") would add up all the subtotals for orders with a status of “Valid”.

Variance
Returns the numeric variance for a given column.

Syntax: Variance(column)

Example: Variance([Temperature]) will return a measure of the dispersion from the mean temperature for all temps in that column.

Related: StandardDeviation, Average.

Functions
Function expressions apply to each individual value. They can be used to alter or filter values in a column, or create new, custom columns.

Logical functions
Logical functions determine if a condition is satisfied or determine what value to return based on a condition.

between
Checks a date or number column’s values to see if they’re within the specified range.

Syntax: between(column, start, end)

Example: between([Created At], "2019-01-01", "2020-12-31") would return rows where Created At date fell within the range of January 1, 2019 and
December 31, 2020.

Related: interval.

case
Tests an expression against a list of cases and returns the corresponding value of the first matching case, with an optional default value if nothing else is met.

Syntax: case(condition, output, …)

Example: case([Weight] > 200, "Large", [Weight] > 150, "Medium", "Small") If a Weight is 250, the expression would return “Large”. In this case, the
default value is “Small”, so any Weight 150 or less would return “Small”.

coalesce
Looks at the values in each argument in order and returns the first non-null value for each row.

Syntax: coalesce(value1, value2, …)

Example: coalesce([Comments], [Notes], "No comments") . If both the Comments and Notes columns are null for that row, the expression will return the string
“No comments”.

isnull
Returns true if the column is null.

Syntax: isnull(column)

Example: isnull([Tax]) would return true if no value were present in the column for that row.

Related: notnull, isempty

notnull
Returns true if the column contains a value.

Syntax: notnull(column)

Example: notnull([Tax]) would return true if there is a value present in the column for that row.

Related: isnull, notempty

Math functions
Math functions implement common mathematical operations.

abs
Returns the absolute (positive) value of the specified column.

Syntax: abs(column)

Example: abs([Debt]) . If Debt were -100, abs(-100) would return 100 .

ceil
Rounds a decimal up (ceil as in ceiling).

Syntax: ceil(column) .

Example: ceil([Price]) . ceil(2.99) would return 3.

Related: floor, round.

exp
Returns Euler’s number, e, raised to the power of the supplied number. (Euler sounds like “Oy-ler”).

Syntax: exp(column) .

Example: exp([Interest Months])

Related: power.

floor
Rounds a decimal number down.

Syntax: floor(column)

Example: floor([Price]) . If the Price were 1.99, the expression would return 1.

Related: ceil, round.

log
Returns the base 10 log of the number.

Syntax: log(column) .

Example: log([Value]) .

power
Raises a number to the power of the exponent value.

Syntax: power(column, exponent) .

Example: power([Length], 2) . If the length were 3 , the expression would return 9 (3 to the second power is 3*3).

Databases that don’t support power : SQLite.

Related: exp.

round
Rounds a decimal number either up or down to the nearest integer value.

Syntax: round(column) .

Example: round([Temperature]) . If the temp were 13.5 degrees centigrade, the expression would return 14 .

Example: round([Temperature] * 10) / 10 . If the temp were 100.75 , the expression would return 100.8 .

sqrt
Returns the square root of a value.

Syntax: sqrt(column) .

Example: sqrt([Hypotenuse]) .

Databases that don’t support sqrt : SQLite.

Related: Power.

String functions
String functions manipulate or validate string data.

concat
Combine two or more strings together.

Syntax: concat(value1, value2, …)

Example: concat([Last Name], ", ", [First Name]) would produce a string of the format “Last Name, First Name”, like “Palazzo, Enrico”.

contains
Checks to see if string1 contains string2 within it.

Performs case-sensitive match by default. You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

Syntax: contains(string1, string2) for case-sensitive match.

contains(string1, string2, "case-insensitive") for case-insensitive match.

Example: contains([Status], "Class") .

If Status were “Classified”, the expression would return true . If the Status were “classified”, the expression would return false , because the case does not match.

Related: doesNotContain, regexextract.

doesNotContain
Checks to see if string1 contains string2 within it.

Performs case-sensitive match by default. You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

Syntax: doesNotContain(string1, string2) for case-sensitive match.

doesNotContain(string1, string2, "case-insensitive") for case-insensitive match.

Example: doesNotContain([Status], "Class") . If Status were “Classified”, the expression would return false .

Related: contains, regexextract.

endsWith
Returns true if the end of the text matches the comparison text.

Performs case-sensitive match by default. You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

Syntax: endsWith(text, comparison) for case-sensitive match.

endsWith(text, comparison, "case-insensitive") for case-insensitive match.

Example: endsWith([Appetite], "hungry")

Related: startsWith, contains, doesNotContain.

isempty
Returns true if a string column contains an empty string or is null. Calling this function on a non-string column will cause an error. You can use isnull for non-string
columns.

Syntax: isempty(column)

Example: isempty([Feedback]) would return true if Feedback was an empty string ( '' ) or did not contain a value.

Related: notempty, isnull

ltrim
Removes leading whitespace from a string of text.

Syntax: ltrim(text)

Example: ltrim([Comment]) . If the comment were " I'd prefer not to" , ltrim would return "I'd prefer not to" .

Related: trim and rtrim.

length
Returns the number of characters in text.

Syntax: length(text)

Example: length([Comment]) . If the comment were “wizard”, length would return 6 (“wizard” has six characters).

lower
Returns the string of text in all lower case.

Syntax: lower(text) .

Example: lower([Status]) . If the Status were “QUIET”, the expression would return “quiet”.

Related: upper.

notempty
Returns true if a string column contains a value that is not the empty string. Calling this function on a non-string column will cause an error. You can use notnull on
non-string columns.

Syntax: notempty(column)

Example: notempty([Feedback]) would return true if Feedback contains a value that isn’t the empty string ( '' ).

Related: isempty, isnull, notnull

regexextract
Extracts matching substrings according to a regular expression.

Syntax: regexextract(text, regular_expression) .

Example: regexextract([Address], "[0-9]+") .

Databases that don’t support regexextract : H2, SQL Server, SQLite.

Related: contains, doesNotContain, substring.

replace
Replaces all occurrences of a search text in the input text with the replacement text.

Syntax: replace(text, find, replace) .

Example: replace([Title], "Enormous", "Gigantic") .

rtrim
Removes trailing whitespace from a string of text.

Syntax: rtrim(text)

Example: rtrim([Comment]) . If the comment were “Fear is the mindkiller. “, the expression would return “Fear is the mindkiller.”

Related: trim and ltrim.

startsWith
Returns true if the beginning of the text matches the comparison text. Performs case-sensitive match by default. You can pass an optional parameter "case-
insensitive" to perform a case-insensitive match.

Syntax: startsWith(text, comparison) for case-sensitive match.

startsWith(text, comparison, "case-insensitive") for case-insensitive match.

Example: startsWith([Course Name], "Computer Science") would return true for course names that began with “Computer Science”, like “Computer Science
101: An introduction”.

It would return false for “Computer science 201: Data structures” because the case of “science” does not match the case in the comparison text.

startsWith([Course Name], "Computer Science", "case-insensitive") would return true for both “Computer Science 101: An introduction” and “Computer
science 201: Data structures”.

Related: endsWith, contains, doesNotContain.

substring
Returns a portion of the supplied text, specified by a starting position and a length.

Syntax: substring(text, position, length)

Example: substring([Title], 1, 10) returns the first 10 letters of a string (the string index starts at position 1).

Related: regexextract, replace.

trim
Removes leading and trailing whitespace from a string of text.

Syntax: trim(text)

Example: trim([Comment]) will remove any whitespace characters on either side of a comment.

upper
Returns the text in all upper case.

Syntax: upper(text) .

Example: upper([Status]) . If status were “hyper”, upper("hyper") would return “HYPER”.

Date functions
Date functions manipulate, extract, or create date and time values.

convertTimezone
Shifts a date or timestamp value into a specified time zone.

Syntax: convertTimezone(column, target, source) .

Example: convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern") would return the value 2022-12-28T09:00:00 , displayed as
December 28, 2022, 9:00 AM .

See the database limitations for convertTimezone .

datetimeAdd
Adds some unit of time to a date or timestamp value.

Syntax: datetimeAdd(column, amount, unit) .

Example: datetimeAdd("2021-03-25", 1, "month") would return the value 2021-04-25 , displayed as April 25, 2021 .

Related: between, datetimeSubtract.

datetimeDiff
Returns the difference between two datetimes in some unit of time. For example, datetimeDiff(d1, d2, "day") will return the number of days between d1 and
d2 .

Syntax: datetimeDiff(datetime1, datetime2, unit) .

Example: datetimeDiff("2022-02-01", "2022-03-01", "month") would return 1 .

datetimeSubtract
Subtracts some unit of time from a date or timestamp value.

Syntax: datetimeSubtract(column, amount, unit) .

Example: datetimeSubtract("2021-03-25", 1, "month") would return the value 2021-02-25 , displayed as February 25, 2021 .

Related: between, datetimeAdd.

day
Takes a datetime and returns the day of the month as an integer.

Syntax: day([datetime column]) .

Example: day("2021-03-25T12:52:37") would return the day as an integer, 25 .

hour
Takes a datetime and returns the hour as an integer (0-23).

Syntax: hour([datetime column]) .

Example: hour("2021-03-25T12:52:37") would return 12 .

interval
Checks a date column’s values to see if they’re within the relative range.

Syntax: interval(column, number, text) .

Example: interval([Created At], -1, "month") .

Related: between.

minute
Takes a datetime and returns the minute as an integer (0-59).

Syntax: minute([datetime column]) .

Example: minute("2021-03-25T12:52:37") would return 52 .

month
Takes a datetime and returns the month number (1-12) as an integer.

Syntax: month([datetime column]) .

Example: month("2021-03-25T12:52:37") would return the month as an integer, 3 .

now
Returns the current date and time using your Metabase report timezone.

Syntax: now .

quarter
Takes a datetime and returns the number of the quarter in a year (1-4) as an integer.

Syntax: quarter([datetime column]) .

Example: quarter("2021-03-25T12:52:37") would return 1 for the first quarter.

relativeDateTime
Gets a timestamp relative to the current time.

Syntax: relativeDateTime(number, text)

number : Period of interval, where negative values are back in time.

text : Type of interval like "day" , "month" , "year"

relativeDateTime can only be used as part of a conditional expression.

Example: [Orders → Created At] < relativeDateTime(-30, "day") will filter for orders created over 30 days ago from current date.

Related: datetimeAdd, datetimeSubtract.

second
Takes a datetime and returns the number of seconds in the minute (0-59) as an integer.

Syntax: second([datetime column]) .

Example: second("2021-03-25T12:52:37") would return the integer 37 .

timeSpan
Gets a time interval of specified length.

Syntax: timeSpan(number, text) .

number : Period of interval, where negative values are back in time.

text : Type of interval like "day" , "month" , "year"

Example: [Orders → Created At] + timeSpan(7, "day") will return the date 7 days after the Created At date.

week
Takes a datetime and returns the week as an integer.

Syntax: week(column, mode) .

Example: week("2021-03-25T12:52:37") would return the week as an integer, 12 .

column: the name of the column of the date or datetime value.

mode: Optional.

ISO: (default) Week 1 starts on the Monday before the first Thursday of January.

US: Week 1 starts on Jan 1. All other weeks start on Sunday.

Instance: Week 1 starts on Jan 1. All other weeks start on the day defined in your Metabase localization settings.

weekday
Takes a datetime and returns an integer (1-7) with the number of the day of the week.

Syntax: weekday(column)

column: The datetime column.

Example:

case(
weekday([Created At]) = 1, "Sunday",
weekday([Created At]) = 2, "Monday",
weekday([Created At]) = 3, "Tuesday",
weekday([Created At]) = 4, "Wednesday",
weekday([Created At]) = 5, "Thursday",
weekday([Created At]) = 6, "Friday",
weekday([Created At]) = 7, "Saturday")

year
Takes a datetime and returns the year as an integer.

Syntax: year([datetime column]) .

Example: year("2021-03-25T12:52:37") would return the year 2021 as an integer, 2,021 .

Limitations

Aggregation expressions can only be used in the Summarize section of the query builder.

Functions that return a boolean value, like isempty or contains, cannot be used to create a custom column. To create a custom column based on one of these
functions, you must combine them with another function, like case .

For example, to create a new custom column that contains true if [Title] contain 'Wallet' , you can use the custom expression

case(contains([Title], 'Wallet'), true, false)

Database limitations
Limitations are noted for each aggregation and function above, and here there are in summary:

H2 (including Metabase Sample Database): Median , Percentile , convertTimezone and regexextract

MySQL/MariaDB: Median , Percentile .

SQL Server: Median , Percentile and regexextract

SQLite: log , Median , Percentile , power , regexextract , StandardDeviation , sqrt and Variance

Vertica: Median and Percentile

Additionally, Presto only provides approximate results for Median and Percentile .

If you’re using or maintaining a third-party database driver, please refer to the wiki to see how your driver might be impacted.

Check out our tutorial on custom expressions in the query builder to learn more.

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
© Metabase 2024
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Creating a new question with the


Installation Asking questions query builder

Metabase’s two core concepts are questions and their corresponding answers. To ask a question in Metabase, click the + New button in the upper right of the main The query builder
Databases
navigation bar, and select either:
Picking data
Questions Question Joining data
SQL query
Questions overview Filtering

Asking questions This page covers how to ask a question using Metabase’s graphical query builder, the “Question” option. Filter types

Visualizing data Filter modal

Custom expressions Creating a new question with the query builder Summarizing and grouping by

List of expressions From the + New dropdown, select Question, then pick your starting data: Grouping your metrics

Joining data Visualizing your data


You can start a question from:
The SQL editor Drill-through menu
A model. A model is a special kind of saved question meant to be used as a good starting point for questions. Sometimes these are called derived tables, as they
SQL parameters Returning to the notebook editor
usually pull together data from multiple raw tables.
Referencing models and saved Viewing an individual record’s
questions Raw data. You’ll need to specify the database and the table in that database as the starting point for your question.
details
SQL snippets A saved question. You can use the results of any question as the starting point for a new question.
Custom expressions
SQL snippet folder permissions Note that there are some kinds of saved questions that can’t be used as source data: Adding or removing columns in a
Sharing answers table
Druid questions
Alerts Sorting results
Mongo questions
Public sharing Setting a row limit
Questions that use Cumulative Sum or Cumulative Count aggregations
Exporting data Viewing the SQL that powers your
Questions that have columns that are named the same or similar thing, like Count and Count 2
question

Dashboards Play around with saved questions

Data modeling
The query builder Question version history

Once you select your data, Metabase will take you to the query builder. Say you selected Raw data > Sample database > Orders, then you’ll see something like this: Further reading
Actions

Organization

People

Permissions

Embedding

Configuration

Tools

Cloud

Metabase API

Troubleshooting

Developer guide

Paid features

This is the query builder’s notebook editor. It has three default steps.

Picking data

Filtering

Summarizing and grouping by

To the right of each completed step is a Preview button (looks like a Play button - a triangle pointing to the right) that shows you the first 10 rows of the results of
your question up to that step.

Picking data
The data section is where you select the data you want to work with. Here you’ll pick a model, a table from a database, or a saved question. You can click on a table to
select which columns you want to include in your results. See also adding or removing columns in a table.

Joining data
You can also select multiple tables from the same database by joining them.

Filtering
Filtering just means narrowing things down based on certain criteria. You’re probably already familiar with filtering when looking for something online, like when
shopping. Maybe you only want to see olive-colored pants, or books where the author’s last name is “Borges,” or pictures of people wearing olive-colored pants
reading Jorge Luis Borges.

When you add a filter step, you can select one or more columns to filter on. Depending on the data type of the column you pick, you’ll get different filter types, like a
calendar for date columns.

You can add subsequent filter steps after each summarize step. This lets you do things like summarize by the count of rows per month, and then add a filter on the
count column to only include rows where the count is greater than 100. (This is basically like a SQL HAVING clause.)

Once you’re happy with your filter, click Add filter, and visualize your results. Your data will be updated with the filter applied.

If you want to edit your filter, just click the little purple filter at the top of the screen. If you click on the X, you’ll remove your filter. You can add as many filters as you
need.

Filter types
Broadly speaking, there are three types of columns, each with their own set of filtering options:

Numeric columns let you add filters to only include rows in your table where this number is between two specific values, or is greater or less than a specific value,
or is exactly equal to something.

Text or category columns let you specify that you only want to include data where this column is or isn’t a specific option, or you can exclude empty cells in that
column.

Date columns give you a lot of options to filter by specific date ranges, relative date ranges, and more.

Filter modal
When viewing a table or chart, clicking on the Filter will bring up the filter modal:

Here you can add multiple filters to your question in one go. Filter options will differ depending on the field type. Any tables linked by foreign keys will be displayed in
the left tab of the modal. When you’re done adding filters, hit Apply filters to rerun the query and update its results. To remove all the filters you’ve applied, click on
Clear all filters in the bottom left of the filter modal. Any filters you apply here will show up in the notebook editor, and vice versa.

Filtering by date
One important thing to understand when filtering on a date column is the difference between specific and relative dates:

Specific dates are things like November 1, 2010, or June 3 – July 12, 2017; they always refer to the same date(s).

Relative dates are things like “the past 30 days,” or “the current week;” as time passes, the dates these options refer to change. Relative dates are a useful way to
set up a filter on a question so that it stays up-to-date by showing you, for example, how many people visited your website in the last 7 days. You can also click on
the … to specify a Starting from option, which lets you offset the relative date range. For example, you could set the range as the “Previous 7 days, starting from 2
days ago”.

Filtering by a segment
If your Metabase administrators have created special named filters for the table you’re viewing, they’ll appear at the top of the filter dropdown in purple text with a
star next to them. These are called Segments, and they’re shortcuts to a combination of filters that are commonly used in your organization. They might be called
things like “Active Users,” or “Most Popular Products.”

Filters with OR
OR

If you have a more complex filter you’re trying to express, you can pick Custom Expression from the add filter menu to create a filter expression. You can use
comparison operators like greater than, > , or less than , < , as well as spreadsheet-like functions. For example, [Subtotal] > 100 OR median([Age]) < 40 . Learn
more about writing expressions or skip right to the list of expressions.

Summarizing and grouping by

When we have a question like “how many people downloaded our app each day last week?”, we’re asking for a summary of the data. A summary is usually made up of
two parts: one or more numbers we care about (called a “metric” in data-speak), and how we want to see that number grouped or broken out. To answer that example
question of “How many people downloaded our app each day last week?”

The metric would be the count of people who downloaded the app (the count of rows).

We want that metric to be grouped by “each day.”

And we want to filter the rows for “last week.”

There are two common ways you’ll tend to summarize your data:

Counting the number of rows in your table

Getting the sum or average of a numeric column

And a lot of the time, you’ll then group that metric by:

Time

Place

Category

Adding a summarize step lets you choose how to aggregate the data from the previous step. You can pick one or more metrics, and optionally group those metrics by
one or more dimensions (columns). When picking your metrics you can choose from basic functions like sum , average , and count ; or you can pick a common metric
defined by an admin; or you can create a custom expression by writing a formula.

Common metrics include:

Count of rows: the total of number of rows in the table, after any filters have been applied. If you’re looking at your Orders table and want to know how many
orders were placed with a price greater than $40, you’d filter by “Price greater than 40,” and then select Count of rows , because you want Metabase to count
how many orders matched your filter.

Sum of …: the sum of all the values in a specific column.

Average of …: the average of all the values in a single column.

Number of distinct values of…: the number of unique values in all the cells of a single column. This is useful when trying to find out things like how many different
types of products were sold last month (not how many were sold in total).

Cumulative sum of…: This gives you a running total for a specific column. In order for this metric to be useful you’ll need to group it by a date column to see it
across time.

Cumulative count of rows: This gives you a running total of the number of rows in the table over time. Just like Cumulative sum of… , you’ll need to group this by
a date column in order for it to be useful.

Standard deviation of …: A number which expresses how much the values of a column vary, plus or minus, from the average value of that column.

Minimum of …: The minimum value present in the selected field.

Maximum of …: The maximum value present in the selected field.

If you summarize and add a grouping you can then summarize again. You can also add steps to filter and/or join in between. For example, your first summarization
step could be to get the count of orders per month, and you could then add a second summarization step to get the average monthly order total by selecting the
Average of… your count column.

You can also add metrics and groupings on the results page in a sidebar: the top of the sidebar where you pick the number (“metric”) you want to see, and the part
below is where you pick how to group that number (or how to “break it out”).

If your admins have created any named metrics that are specific to your company or organization, they will be in this dropdown under the Common Metrics section.
These might be things like your company’s official way of calculating revenue.

Grouping your metrics


Depending on the grouping column you select, Metabase will show you what it thinks is the best default visualization or chart for this summary. So if you select a date
column, you’ll see a line chart like this (you can click the green Summarize button to view the summarize sidebar).

When you click on a different grouping column than the one you currently have selected, the grouping will switch to use that column instead. But if you want to add
an additional grouping, just click the plus (+) icon on the right side of the column. To remove a grouping, click on the X icon.

Some grouping columns will give you the option of choosing how big or small to make the groupings. So for example, if you’ve picked a Date column to group by, you
can click on the words by month to change the grouping to day, week, hour, quarter, year, etc. If you’re grouping by a numeric column, like age, Metabase will
automatically “bin” the results, so you’ll see your metric grouped in age brackets, like 0–10, 11–20, 21–30, etc. Just like with dates, you can click on the current
binning option to change it to a specific number of bins. It’s not currently possible to choose your own ranges for bins, though.

Once you’re done setting your metrics and groupings, click Visualize to see your results in all their glory.

Visualizing your data


If you want to jump ahead and learn about how to change the visualization of your results, by all means, feel free.

Drill-through menu
You can also click through questions to explored the data in greater detail.

The drill-through menu will present different options depending on what you click on. You can then optionally save that exploration as a new question. The drill-
through menu is only available for questions built using the query builder. For more on how drill-through works, check out Creating interactive charts.

Returning to the notebook editor


To return to the notebook editor for a question, click on the show editor button in the upper right.

Viewing an individual record’s details


To see more info about a given record (a user, order, venue, etc.), click on a record’s ID number (or primary key). You can see all fields related to that one record and all
connected tables that are hidden in the table view for the sake of readability. To page through the other records in the current table, press the right or left arrow keys,
or click on the arrows to the right or left of the screen.
Custom expressions
Custom expressions allow you to use spreadsheet-like functions and simple arithmetic within or between aggregation functions.

For example, you could do Average(sqrt[FieldX]) + Sum([FieldY]) or Max(floor([FieldX] - [FieldY])) , where FieldX and FieldY are fields in the
currently selected table. Learn more about writing expressions.

Creating custom columns

Custom columns are helpful when you need to create a new column based on a calculation, such as subtracting the value of one column from another, or extracting a
portion of an existing text column. Custom columns that you add aren’t permanently added to your table; they’ll only be present in the given question.

You can use the following math operators in your formulas: + , – , * (multiplication), and / (division), along with a whole host of spreadsheet-like functions. You can
also use parentheses to clarify the order of operations.

Adding or removing columns in a table


When viewing tables, you can click on the gear icon in the bottom left to bring up the columns picker. Click Add or remove columns to search for and pick columns,
including columns from related tables.

Sorting results

The sorting step lets you pick one or more columns to sort your results by. For each column you pick, you can also choose whether to sort ascending or descending;
just click the arrow to change from ascending (up arrow) to descending (down arrow).

Setting a row limit


The row limit step lets you limit how many rows you want from the previous results. When used in conjunction with sorting, this can let you do things like create a
top-10 list, by first sorting by one of the columns in your result, then adding a row limit of 10. Unlike other steps, the row limit step can only be added at the end of
your question.

Viewing the SQL that powers your question


Under the hood, all Metabase questions are SQL (gasp!). If you’re curious to see the SQL that will get run when you ask your question, you can click the little console
icon in the top-right of the notebook editor. In the modal that opens up, you’ll also be given the option to start a new query in the SQL editor using this generated SQL
as a starting point (assuming you have SQL permissions to that database). It’s a nice little shortcut to have Metabase write some boilerplate SQL for you, but then
allows you to tweak and customize the query.

Play around with saved questions


Each time you start modifying a saved question, Metabase will create a new question for you. The query builder will display the name of your starting question under
Data.

Feel free to play around with any saved question, as you won’t have any effect on the existing question. When you hit Save on the question, you can choose either to
save as a new question (the default), or you can overwrite the existing question you started from.

If you find yourself using the same saved question as a starting point for multiple questions, you may want to turn it into a model to let others know it’s a good
starting place.

Question version history


For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item.

See History.

Further reading

Visualize results.

Sharing answers.

Asking questions

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
© Metabase 2024
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Multiple stages of joins


Installation Joining data
Joining on multiple conditions
Databases Joining with different operators

Questions Further reading

Questions overview

Asking questions

Visualizing data

Custom expressions

List of expressions

Joining data

The SQL editor

SQL parameters
You can join data to combine your current data with another table, or even with a saved question.
Referencing models and saved
questions
After you click on the Join Data button to add a join step, you’ll need to pick the data (from the same database) that you want to join. You can only pick tables and
SQL snippets saved questions that are from the same database as your starting data.
SQL snippet folder permissions

Sharing answers

Alerts

Public sharing

Exporting data

Dashboards

Data modeling

Actions

Organization

People

Permissions

Embedding
Next, you’ll need to pick the columns you want to join on. This means you pick a column from the first table, and a column from the second table, and the join will
stitch rows together where the value from the first column is equal to the value in the second column. A very common example is to join on an ID column in each
Configuration
table, so if you happened to pick a table to join on where there is a foreign key relationship between the tables, Metabase will automatically pick those corresponding
ID columns for you. At the end of your join step, there’s a Columns button you can click to choose which columns you want to include from the joined data.
Tools
By default, Metabase will do a left outer join, but you can click on the Venn diagram icon to select a different type of join. Not all databases support all types of joins,
Cloud so Metabase will only display the options supported by the database you’re using.

Metabase API Here are the basic types of joins:

Left outer join: select all records from Table A, along with records from Table B that meet the join condition, if any.
Troubleshooting
Right outer join: select all records from Table B, along with records from Table A that meet the join condition, if any.
Developer guide Inner join: only select the records from Table A and B where the join condition is met.

Full outer join: select all records from both tables, whether or not the join condition is met.
Paid features

A left outer join example: If Table A is Orders and Table B is Customers, and assuming you do a join where the customer_id column in Orders is equal to the ID
column in Customers, when you do a left outer join your results will be a full list of all your orders, and each order row will also display the columns of the customer
who placed that order. Since a single customer can place many orders, a given customer’s information might be repeated many times for different order rows. If there
isn’t a corresponding customer for a given order, the order’s information will be shown, but the customer columns will just be blank for that row.

Multiple stages of joins


In many cases you might have tables A, B, and C, where A and B have a connection, and B and C have a connection, but A and C don’t. If you want to join A to B to C, all
you have to do is add multiple join steps. Click on Join Data, join table A to table B, then click the Join Data step below that completed join block to add a second join
step, and join the results of your last join to table C.

Joining on multiple conditions


Your joins can also include multiple conditions to refine your results. Metabase will combine multiple conditions using the AND operator.

Joining with different operators


You can join tables on comparison conditions like = , ≠ , > , ≥ , < , or ≤ .

Further reading

Joins in Metabase

Type of joins

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation DatetimeDiff
Calculating age
datetimeDiff gets the amount of time between two datetime values, using the specified unit of time. Note that the difference is calculated in whole units (see the
Databases
example below). Accepted data types

Questions Limitations
S Y NTAX EXAMPL E
Related functions
Dashboards
datetimeDiff(datetime1, datetime2, unit) datetimeDiff("2022-02-01", "2022-03-01", Further reading
"month")
Data modeling

Actions Gets the difference between two datetimes (datetime2 minus datetime 1) using the specified unit 1
of time.
Organization

People

Permissions

Parameters
Embedding
datetime1 and datetime2 can be:

Configuration
The name of a timestamp column,

Tools a custom expression that returns a datetime, or

a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS" (as shown in the example above).
Cloud
unit can be any of:
Metabase API
“year”
Troubleshooting “quarter”

“month”
Developer guide
“week”
Paid features “day”

“hour”

“minute”

“second”

Calculating age
Let’s say you’re a cheesemaker, and you want to keep track of your ripening process:

CH E ES E AGIN G S TART AGING EN D MAT URE AGE ( MO NT HS )

Provolone January 19, 2022 March 17, 2022 1

Feta January 25, 2022 May 3, 2022 3

Monterey Jack January 27, 2022 October 11, 2022 8

Mature Age (Months) is a custom column with the expression:

datetimeDiff([Aging Start], [Aging End], "month")

To calculate the current age of a cheese in months, you use now


now as the second datetime parameter, like this:

datetimeDiff([Aging Start], now, "month")

To calculate the current age of a cheese in days, you’d use:

datetimeDiff([Aging Start], now, "day")

Accepted data types


DATA T Y PE W ORK S WIT H DDDAAATTTEEETTTIIIMMMEEEDDDIIIFFFFFF

String

Number

Timestamp

Boolean

JSON

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see
Timezones.

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

Limitations
datetimeDiff is currently unavailable for the following databases:

Druid

Google Analytics

Related functions
This section covers functions and formulas that work the same way as the Metabase datetimeDiff expression, with notes on how to choose the best option for your
use case.

SQL

Spreadsheets

Python

SQL
When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our cheese sample data is stored in a PostgreSQL database:

SELECT DATE_PART('month', AGE(aging_end, aging_start)) AS mature_age_months


FROM cheese

is equivalent to the Metabase datetimeDiff expression:

datetimeDiff([Aging Start], [Aging End], "month")

Some databases, such as Snowflake and BigQuery, support functions like DATEDIFF or DATE_DIFF . For more info, check out our list of common SQL reference guides.

Spreadsheets
If our cheese sample data is in a spreadsheet where “Aging Start” is in column B and “Aging End” is in column C:

DATEDIF(B1, C1, "M")

produces the same result as

datetimeDiff([Aging Start], [Aging End], "month")

Yes, DATEDIF looks a bit wrong, but the spreadsheet function really is DATEDIF() with one “f”, not DATEDIFF() .

Python
Assuming the cheese sample data is in a pandas dataframe column called df , you can subtract the dates directly and use numpy ’s timedelta64 to convert the
difference to months:

df['Mature Age (Months)'] = (df['Aging End'] - df['Aging Start']) / np.timedelta64(1, 'M')

is equivalent to

datetimeDiff([Aging Start], [Aging End], "month")

Further reading

Custom expressions documentation

Custom expressions tutorial

Time series analysis

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation CountIf
Multiple conditions
CountIf counts the total number of rows in a table that match a condition. CountIf counts every row, not just unique rows.
Databases Conditional counts by group
Syntax: CountIf(condition) .
Questions Accepted data types

Example: in the table below, CountIf([Plan] = "Basic") would return 3. Related functions
Dashboards
Further reading
ID PLAN

Data modeling
1 Basic
Actions

2 Basic
Organization

People 3 Basic

Permissions
4 Business

Embedding
5 Premium
Configuration

Tools

Cloud

Metabase API Aggregations like CountIf should be added to the query builder’s Summarize menu > Custom Expression (scroll down in the menu if needed).

Troubleshooting

Developer guide
Parameters
Paid features
CountIf accepts a function or conditional statement that returns a boolean value ( true or false ).

Multiple conditions
We’ll use the following sample data to show you CountIf with required, optional, and mixed conditions.

ID P LA N ACT IVE SUBS CRIPT ION

1 Basic true

2 Basic true

3 Basic false

4 Business false

5 Premium true

Required conditions
To count the total number of rows in a table that match multiple required conditions, combine the conditions using the AND operator:

CountIf(([Plan] = "Basic" AND [Active Subscription] = true))

This expression will return 2 on the sample data above (the total number of Basic plans that have an active subscription).

Optional conditions
To count the total rows in a table that match multiple optional conditions, combine the conditions using the OR operator:

CountIf(([Plan] = "Basic" OR [Active Subscription] = true))

Returns 4 on the sample data: there are three Basic plans, plus one Premium plan has an active subscription.

Some required and some optional conditions


To combine required and optional conditions, group the conditions using parentheses:

CountIf(([Plan] = "Basic" OR [Plan] = "Business") AND [Active Subscription] = "false")

Returns 2 on the sample data: there are only two Basic or Business plans that lack an active subscription.

Tip: make it a habit to put parentheses around your AND and OR groups to avoid making required conditions optional (or vice versa).

Conditional counts by group


In general, to get a conditional count for a category or group, such as the number of inactive subscriptions per plan, you’ll:

1. Write a CountIf expression with your conditions.

2. Add a Group by column in the query builder.

Using the sample data:

ID P LA N ACT IVE SUBS CRIPT ION

1 Basic true

2 Basic true

3 Basic false

4 Business false

5 Premium true

Count the total number of inactive subscriptions per plan:

CountIf([Active Subscription] = false)

Alternatively, if your Active Subscription column contains null (empty) values that represent inactive plans, you could use:

CountIf([Payment], [Plan] != true)

The “not equal” operator != should be written as !=.

To view your conditional counts by plan, set the Group by column to “Plan”.

P LA N TOTAL INACT IVE SUBS CRIPT IO NS

Basic 1

Business 1

Premium 0

Tip: when sharing your work with other people, it’s helpful to use the OR filter, even though the != filter is shorter. The inclusive OR filter makes it easier to
understand which categories (e.g., plans) are included in your conditional count.

Accepted data types


DATA T Y PE W ORK S WIT H CCCOOOUUUNNNTTTIIIFFF

String

Number

Timestamp

Boolean

JSON

CountIf accepts a function or conditional statement that returns a boolean value ( true or false ).

Related functions
Different ways to do the same thing, because it’s fun to try new things.

Metabase

case

CumulativeCount

Other tools

SQL

Spreadsheets

Python

case
You can combine Count
Count with case
case:

Count(case([Plan] = "Basic", [ID]))

to do the same thing as CountIf :

CountIf([Plan] = "Basic")

The case version lets you count a different column when the condition isn’t met. For example, if you’ve got data from different sources:

I D: S OU RC E A P LA N: S OURC E A ID: SO URC E B PLAN: SO URCE B

1 Basic

B basic

C basic

4 Business D business

5 Premium E premium

To count the total number of Basic plans across both sources, you could create a case expression to:

Count the rows in “ID: Source A” where “Plan: Source A = “Basic”

Count the rows in “ID: Source B” where “Plan: Source B = “basic”

Count(case([Plan: Source A] = "Basic", [ID: Source A],


case([Plan: Source B] = "basic", [ID: Source B])))

CumulativeCount
CountIf doesn’t do running counts. You’ll need to combine CumulativeCount with case
case.

If our sample data is a time series:

ID P LA N ACT IVE SUBS CRIPT ION CREAT ED DATE

1 Basic true October 1, 2020

2 Basic true October 1, 2020

3 Basic false October 1, 2020

4 Business false November 1, 2020

5 Premium true November 1, 2020

And we want to get the running count of active plans like this:

CR EATE D DAT E: M ON TH TOTAL ACT IVE PLAN S TO DAT E

October 2020 2

November 2020 3

Create an aggregation from Summarize > Custom expression:

CumulativeCount(case([Active Subscription] = true, [ID]))

You’ll also need to set the Group by column to “Created Date: Month”.

SQL
When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query
against your database to get your results.

If our sample data is stored in a PostgreSQL database, the SQL query:

SELECT COUNT(CASE WHEN plan = "Basic" THEN id END) AS total_basic_plans


FROM accounts

is equivalent to the Metabase expression:

CountIf([Plan] = "Basic")

If you want to get conditional counts broken out by group, the SQL query:

SELECT
plan,
COUNT(CASE WHEN active_subscription = false THEN id END) AS total_inactive_subscriptions
FROM accounts
GROUP BY
plan

The SELECT part of the SQl query matches the Metabase expression:

CountIf([Active Subscription] = false)

The GROUP BY part of the SQL query matches a Metabase Group by set to the “Plan” column.

Spreadsheets
If our sample data is in a spreadsheet where “ID” is in column A, the spreadsheet formula:

=CountIf(B:B, "Basic")

produces the same result as the Metabase expression:

CountIf([Plan] = "Basic")

Python
If our sample data is in a pandas dataframe column called df , the Python code:

len(df[df['Plan'] == "Basic"])

uses the same logic as the Metabase expression:

CountIf([Plan] = "Basic")

To get a conditional count with a grouping column:

## Add your conditions

df_filtered = df[df['Active subscription'] == false]

## Group by a column, and count the rows within each group

len(df_filtered.groupby('Plan'))

The Python code above will produce the same result as the Metabase CountIf expression (with the Group by column set to “Plan”).

CountIf([Active Subscription] = false)

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation SumIf
Multiple conditions
SumIf adds up the values in a column based on a condition.
Databases Conditional subtotals by group
Syntax: SumIf(column, condition) .
Questions Accepted data types

Example: in the table below, SumIf([Payment], [Plan] = "Basic") would return 200. Related functions
Dashboards
Further reading
PAY M E NT PLAN

Data modeling
100 Basic
Actions

100 Basic
Organization

People 200 Business

Permissions
200 Business

Embedding
400 Premium
Configuration

Tools

Cloud

Metabase API Aggregation formulas like sumif should be added to the query builder’s Summarize menu > Custom Expression (scroll down in the menu if needed).

Troubleshooting

Developer guide
Parameters
Paid features
column can be the name of a numeric column, or a function that returns a numeric column.

condition is a function or conditional statement that returns a boolean value ( true or false ), like the conditional statement [Payment] > 100 .

Multiple conditions
We’ll use the following sample data to show you SumIf with required, optional, and mixed conditions.

PAY M E NT P LA N DAT E RECEIVED

100 Basic October 1, 2020

100 Basic October 1, 2020

200 Business October 1, 2020

200 Business November 1, 2020

400 Premium November 1, 2020

Required conditions
To sum a column based on multiple required conditions, combine the conditions using the AND operator:

SumIf([Payment], ([Plan] = "Basic" AND month([Date Received]) = 10))

This expression would return 200 on the sample data above: the sum of all of the payments received for Basic Plans in October.

Optional conditions
To sum a column with multiple optional conditions, combine the conditions using the OR operator:

SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business"))

Returns 600 on the sample data.

Some required and some optional conditions


To combine required and optional conditions, group the conditions using parentheses:

SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business") AND month([Date Received]) = 10)

Returns 400 on the sample data.

Tip: make it a habit to put parentheses around your AND and OR groups to avoid making required conditions optional (or vice versa).

Conditional subtotals by group


To get a conditional subtotal for a category or group, such as the total payments per plan, you’ll:

1. Write a sumif formula with your conditions.

2. Add a Group by column in the query builder.

PAY M E NT P LA N DAT E RECEIVED

100 Basic October 1, 2020

100 Basic October 1, 2020

200 Business October 1, 2020

200 Business November 1, 2020

400 Premium November 1, 2020

To sum payments for the Business and Premium plans:

SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")

Or, sum payments for all plans that aren’t “Basic”:

SumIf([Payment], [Plan] != "Basic")

The “not equal” operator != should be written as !=.

To view those payments by month, set the Group by column to “Date Received: Month”.

DATE RE C EI V E D: M ON TH TOTAL PAYMENT S FOR BUSINES S AND PREMIUM PLANS

October 200

November 600

Tip: when sharing your work with other people, it’s helpful to use the OR filter, even though the != filter is shorter. The inclusive OR filter makes it easier to
understand which categories (e.g., plans) are included in the sum.

Accepted data types


DATA T Y PE W ORK S W IT H SSSUUUMMMIIIFFF

String

Number

Timestamp

Boolean

JSON

See parameters.

Related functions
Different ways to do the same thing, because CSV files still make up 40% of the world’s data.

Metabase

case

CumulativeSum

Other tools

SQL

Spreadsheets

Python

case
You can combine Sum
Sum and case
case:

Sum(case([Plan] = "Basic", [Payment]))

to do the same thing as SumIf :

SumIf([Payment], [Plan] = "Basic")

The case version lets you sum a different column when the condition isn’t met. For example, you could create a column called “Revenue” that:

sums the “Payments” column when “Plan = Basic”, and

sums the “Contract” column otherwise.

sum(case([Plan] = "Basic", [Payment], [Contract]))

CumulativeSum
SumIf doesn’t do running totals. You’ll need to combine the CumulativeSum aggregation with the case
case formula.

For example, to get the running total of payments for the Business and Premium plans by month (using our payment sample data):

DATE RE C EI V E D: M ON TH TOTAL PAYMENT S FOR BUSINES S AND PREMIUM PLANS

October 200

November 800

Create an aggregation from Summarize > Custom expression:

CumulativeSum(case(([Plan] = "Basic" OR [Plan] = "Premium"), [Payment], 0))

Don’t forget to set the Group by column to “Date Received: Month”.

SQL
When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query
against your database to get your results.

If our payment sample data is stored in a PostgreSQL database, the SQL query:

SELECT
SUM(CASE WHEN plan = "Basic" THEN payment ELSE 0 END) AS total_payments_basic
FROM invoices

is equivalent to the Metabase expression:

SumIf([Payment], [Plan] = "Basic")

To add multiple conditions with a grouping column, use the SQL query:

SELECT
DATE_TRUNC("month", date_received) AS date_received_month,
SUM(CASE WHEN plan = "Business" THEN payment ELSE 0 END) AS total_payments_business_or_premium
FROM invoices
GROUP BY
DATE_TRUNC("month", date_received)

The SELECT part of the SQl query matches the Metabase SumIf expression:

SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")

The GROUP BY part of the SQL query maps to a Metabase Group by column set to “Date Received: Month”.

Spreadsheets
If our payment sample data is in a spreadsheet where “Payment” is in column A and “Date Received” is in column B, the spreadsheet formula:

=SUMIF(B:B, "Basic", A:A)

produces the same result as the Metabase expression:

SumIf([Payment], [Plan] = "Basic")

To add additional conditions, you’ll need to switch to a spreadsheet array formula.

Python
If our payment sample data is in a pandas dataframe column called df , the Python code:

df.loc[df['Plan'] == "Basic", 'Payment'].sum()

is equivalent to the Metabase expression:

SumIf([Payment], [Plan] = "Basic")

To add multiple conditions with a grouping column:

import datetime as dt

## Optional: convert the column to a datetime object

df['Date Received'] = pd.to_datetime(df['Date Received'])

## Extract the month and year

df['Date Received: Month'] = df['Date Received'].dt.to_period('M')

## Add your conditions

df_filtered = df[(df['Plan'] == 'Business') | (df['Plan'] == 'Premium')]

## Sum and group by

df_filtered.groupby('Date Received: Month')['Payment'].sum()

These steps will produce the same result as the Metabase SumIf expression (with the Group by column set to “Date Received: Month”).

SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Bucketing data for frequency


Installation Case tables or histograms

case checks if a value matches a list of conditions, and returns some output based on the first condition that’s met. Basically, case works the same way as “if… then” Labeling a row based on conditions
Databases
logic, but it’s much nicer to write. from multiple columns

Questions Aggregating data based on


You can optionally tell case to return a default output if none of the conditions are met. If you don’t set a default output, case will return null after checking all of
conditions from multiple columns
your conditions ( null values are displayed as blank values in Metabase).
Dashboards Accepted data types
Use the case expression whenever you need to:
Limitations
Data modeling
bucket a range of values, Related functions
Actions label the rows in your dataset, or Further reading
aggregate rows based on conditional logic.
Organization

S Y NTAX
People

case(condition1, output1, condition2, output2, ..., default_output)


Permissions

Embedding Returns the output from the first condition that’s met.

Configuration

Tools
E XA MP LE

Cloud
case(isempty("glass half full"), "empty glass", isnull("glass half full"), "missing glass", "glass half full")
Metabase API

“glass half full”


Troubleshooting

Developer guide

Paid features

Bucketing data for frequency tables or histograms


A M OUN T BUC KET

6 0-9

18 10-19

31 30-39

57 50+

where Bucket is a custom column with the expression:

case([Amount] >= 0 AND [Amount] <= 9, "0-9",


[Amount] >= 10 AND [Amount] <= 19, "10-19",
[Amount] >= 20 AND [Amount] <= 29, "20-29",
[Amount] >= 30 AND [Amount] <= 39, "30-39",
[Amount] >= 40 AND [Amount] <= 49, "40-49", "50+")

Labeling a row based on conditions from multiple columns


S I GHT IN G I D H AS W INGS HAS FACE SIGH TING TYPE

1 True True Bird

2 True False Plane

3 False False Superman

4 False True Unknown

where Sighting Type is a custom column with the expression:

case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird",


[Has Wings] = TRUE AND [Has Face] = FALSE, "Plane",
[Has Wings] = FALSE AND [Has Face] = TRUE, "Superman"), "Unknown")

You can use the columns holding your “labels” to:

Apply business definitions or business logic to your datasets.

Power a filter.

Segment data for data sandboxing.

Aggregating data based on conditions from multiple columns


You can combine case with aggregate functions to only aggregate rows that meet your conditions.

For example, if we want to count the unique number of orders for each order date, but only those with a “Shipped” status:

ORDE R ID O RDER DAT E STAT US

1 2022-04-01 Paid

1 2022-04-03 Shipped

2 2022-05-12 Paid

2 2022-05-12 Cancelled

1. Create the custom expression distinct(case([Status] = "Shipped", [Order ID])) and name it “Total Orders Shipped”.

2. Choose Order Date as the group by column.

3. Click Visualize to return the result:

ORDE R DAT E TOTAL ORDERS S HIPPED

2022-04-01 1

2022-05-01 0

Accepted data types


DATA T Y PE W ORK S WIT H CCCAAASSSEEE

String

Number

Timestamp

Boolean

JSON

Limitations
All of the outputs must have the same data type.

Avoid::

case(condition1, "string", condition2, TRUE, condition3, 1)

Do::

case(condition1, "string", condition2, "TRUE", condition3, "1")

Related functions
This section covers functions and formulas that can be used interchangeably with the Metabase case expression, with notes on how to choose the best option for
your use case.

Metabase expressions

Coalesce

Countif

Sumif

Other tools

SQL

Spreadsheets

Python

Coalesce
Using the table from the Coalesce: Consolidating values example:

N OTE S C OMM E NT S CCCOOOAAALLLEEESSSCCCEEE((([[[NNNOOOTTTEEESSS]]],,, [[[CCCOOOMMMMMMEEENNNTTTSSS]]] """NNNOOO NNNOOOTTTEEESSS OOORRR CCCOOOMMMMMMEEENNNTTTSSS...""")))

I have a note. I have a comment. I have a note.

I have a comment. I have a comment.

I have a note. I have a note.

No notes or comments.

The Metabase coalesce


coalesce expression

coalesce([Notes], [Comments] "No notes or comments.")

is equivalent to the case expression

case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes],


ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = False, [Comments],
ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE, [Notes],
ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = TRUE, "No notes or comments")

coalesce is much nicer to write if you don’t mind taking the first value when both of your columns are non-blank. Use case if you want to define a specific output for
this case (such as, “I have a note and a comment”).

Countif
Using the table from the Aggregating data example:

ORDE R ID O RDER DAT E STAT US

1 2022-04-01 Paid

1 2022-04-03 Shipped

2 2022-05-12 Paid

2 2022-05-12 Cancelled

The Metabase countif


countif expression

countif(case([Status] = "Shipped"))

is equivalent to the case expression:

count(case([Status] = "Shipped", [Row ID]))

countif is equivalent to case when you are counting all rows in the table that meet your conditions. It is not equivalent if you want to count unique rows that meet
your conditions.

Sumif
Using an expanded version of the table from the Aggregating data example:

ROW I D ORDE R ID O RDER DAT E STAT US AMOU NT

1 1 2022-04-01 Paid $20

2 1 2022-04-03 Shipped $20

3 2 2022-05-12 Paid $80

4 2 2022-05-12 Cancelled $80

The Metabase sumif


sumif expression

sumif([Amount], [Status] = "Shipped")

is equivalent to the case expression:

sum(case([Status] = "Shipped", [Amount]))

sumif is equivalent to case when you sum a single column for single condition.

You should use case if you want to sum a second column under a second, separate condition. For example, if you want to sum the Amount column when Status =
“Shipped” and another (hypothetical) column like Refunded Amount when Status = “Refunded”.

SQL
In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or
data warehouse. Metabase case expressions are converted into SQL CASE WHEN statements.

Using the table from the Labeling rows example:

S I GHT IN G I D H AS W INGS HAS FACE SIGH TING TYPE

1 True True Bird

2 True False Plane

3 False False Superman

4 False True Unknown

The SQL CASE WHEN statement:

SELECT
CASE WHEN "Has Wings" = TRUE AND "Has Face" = TRUE THEN "Bird"
WHEN "Has Wings" = TRUE AND "Has Face" = FALSE THEN "Plane"
WHEN "Has Wings" = FALSE AND "Has Face" = TRUE THEN "Superman"
ELSE "Unknown" END
FROM mystery_sightings

is equivalent to the case expression used for Sighting Type:

case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird",


[Has Wings] = TRUE AND [Has Face] = FALSE, "Plane",
[Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown")

For example, this SQL trick to order bar charts could be written using a Metabase case expression instead.

Spreadsheets
Using the table from the Labeling rows example:

S I GHT IN G I D H AS W INGS HAS FACE SIGH TING TYPE

1 True True Bird

2 True False Plane

3 False False Superman

4 False True Unknown

The spreadsheet formula

=IF(AND(B2 = TRUE, C2 = TRUE), "Bird",


IF(AND(B2 = TRUE, C2 = FALSE), "Plane",
IF(AND(B2 = FALSE, C2 = TRUE), "Superman", "Unknown")
)
)

is equivalent to the case expression used for Sighting Type:

case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird",


[Has Wings] = TRUE AND [Has Face] = FALSE, "Plane",
[Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown")

Python
There are many ways to implement conditional logic using Python. We’ll cover the approaches that make sense to convert into Metabase case expressions.

Using the table from the Labeling rows example (and assuming it’s in a dataframe called df ):

S I GHT IN G I D H AS W INGS HAS FACE SIGH TING TYPE

1 True True Bird

2 True False Plane

3 False False Superman

4 False True Unknown

numpy select()

conditions = [
(df["has_wings"] == True) & (df["has_face"] == True),
(df["has_wings"] == True) & (df["has_face"] == False),
(df["has_wings"] == False) & (df["has_face"] == True)]

outputs = ["Bird", "Plane", "Superman"]

df["Sighting Type"] = np.select(conditions, outputs, default="Unknown")

Helper function with pandas apply()

def Identify(df):
if ((df["has_wings"] == True) & (df["has_face"] == True)):
return "Bird"
elif ((df["has_wings"] == True) & (df["has_face"] == False)):
return "Plane"
elif ((df["has_wings"] == False) & (df["has_face"] == True)):
return "Superman"
else:
return "Unknown"

df["Sighting Type"]= df.apply(Identify, axis=1)

The approaches above are equivalent to the case expression used for Sighting Type:

case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird",


[Has Wings] = TRUE AND [Has Face] = FALSE, "Plane",
[Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown")

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Filling in empty or null values


Installation Coalesce
Consolidating values from
coalesce looks at the values in a list (in order), and returns the first non-null value. different columns
Databases

This function is useful when you want to: Creating calculations across
Questions different columns
fill in missing data,
Accepted data types
Dashboards consolidate data from multiple columns, or
Limitations
create calculations across multiple columns.
Data modeling Related functions

S Y NTAX EXAMPL E Further reading


Actions

coalesce(value1, value2, …) coalesce("null", "null", "bananas", "null" …)


Organization

People Returns the first non-null value from a list of values. “bananas”

Permissions

Embedding

Configuration
Filling in empty or null values
Tools LE F T_ TAB L E_ C OL RI GH T_TABLE_CO L CCCOOOAAALLLEEESSSCCCEEE((([[[RRRIIIGGGHHHTTT___TTTAAABBBLLLEEE___CCCOOOLLL]]],,, 000)))

Cloud 1 1 1

Metabase API
2 null 0

Troubleshooting
3 null 0
Developer guide

4 4 4
Paid features

You may want to fill in empty or null values if you have:

Sparse data.

null values created by a left join (the example shown above).

For a more detailed example, see Filling in data for missing report dates.

Consolidating values from different columns


N OTE S C OMM E NT S CCCOOOAAALLLEEESSSCCCEEE((([[[NNNOOOTTTEEESSS]]],,, [[[CCCOOOMMMMMMEEENNNTTTSSS]]] """NNNOOO NNNOOOTTTEEESSS OOORRR CCCOOOMMMMMMEEENNNTTTSSS...""")))

I have a note. I have a comment. I have a note.

I have a comment. I have a comment.

I have a note. I have a note.

No notes or comments.

Creating calculations across different columns


S U B TOTA L DI S COU NT CCCOOOAAALLLEEESSSCCCEEE((([[[SSSUUUBBBTTTOOOTTTAAALLL]]],,, 000))) --- CCCOOOAAALLLEEESSSCCCEEE((([[[DDDIIISSSCCCOOOUUUNNNTTT]]],,, 000)))

10.00 0.15 9.85

21.00 21.00

16.00 1.60 14.40

4.00 4.00

Calculations in Metabase will return null if any of the input columns are null . This is because null values in your data represent “missing” or “unknown”
information, which isn’t necessarily the same as an amount of “0”. That is, adding 1 + “unknown” = “unknown”.

If you want to treat “unknown” values as zeroes (or some other value that means “nothing” in your data), we recommend using coalesce to wrap the columns used in
your calculations.

Accepted data types


DATA T Y PE W ORK S WIT H CCCOOOAAALLLEEESSSCCCEEE

String

Number

Timestamp

Boolean

JSON

Limitations
Use the same data types within a single coalesce function. If you want to coalesce values that have different data types:

Use the SQL CAST operator.

Change the data type from the Table Metadata page.

If you want to use coalesce with JSON or JSONB data types, you’ll need to flatten the JSON objects first. For more information, look up the JSON functions that are
available in your SQL dialect. You can find some common SQL reference guides here.

Related functions
This section covers functions and formulas that can be used interchangeably with the Metabase coalesce expression, with notes on how to choose the best option
for your use case.

Metabase expressions

case

Other tools

SQL

Spreadsheets

Python

All examples use the custom expression and sample data from the Consolidating values example:

N OTE S C OMM E NT S CCCOOOAAALLLEEESSSCCCEEE((([[[NNNOOOTTTEEESSS]]],,, [[[CCCOOOMMMMMMEEENNNTTTSSS]]] """NNNOOO NNNOOOTTTEEESSS OOORRR CCCOOOMMMMMMEEENNNTTTSSS...""")))

I have a note. I have a comment. I have a note.

I have a comment. I have a comment.

I have a note. I have a note.

No notes or comments.

Case
The Metabase case
case expression

case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes],


ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = False, [Comments],
ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE, [Notes],
ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = TRUE, "No notes or comments")

is equivalent to the Metabase coalesce expression:

coalesce([Notes], [Comments] "No notes or comments.")

coalesce is much nicer to write if you don’t mind taking the first value when both of your columns are non-blank. Use case
case if you want to define a specific output
(e.g., if you want to return “I have a note and a comment” instead of “I have a note”.).

SQL
In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or
data warehouse.

The SQL coalesce function

SELECT
COALESCE(notes, comments, "no notes or comments")
FROM
sample_table;

is equivalent to the Metabase coalesce expression:

coalesce([Notes], [Comments] "No notes or comments.")

Spreadsheets
If your notes and comments table is in a spreadsheet where “Notes” is in column A, and “Comments” is in column B, then the formula

=IF(ISBLANK($A2),$B2,IF(ISBLANK($B2),$A2,"No notes or comments."))

is equivalent to the Metabase coalesce expression:

coalesce([Notes], [Comments] "No notes or comments.")

Alternatively, you may be used to working with a INDEX and MATCH in an array formula if you’re “coalescing” data across three or more columns in a spreadsheet.

Python
Assuming the notes and comments table is in a dataframe called df , the combination of pandas functions combine_first() and fillna()

df['custom_column'] = df['notes'].combine_first(df['comments'])\
.fillna('No notes or comments.')

are equivalent to the Metabase coalesce expression:

coalesce([Notes], [Comments] "No notes or comments.")

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Syntax
Installation Isnull
How Metabase handles nulls
isnull checks if a value is a null , a special kind of placeholder that’s used by a database when something is missing or unknown.
Databases Creating a boolean custom column

Questions Replacing null values with another


Syntax value

Dashboards Accepted data types

isnull(text column) Limitations


Data modeling
Related functions
Actions You can use isnull in custom filters, or as the condition for conditional aggregations CountIf
CountIf and SumIf
SumIf. To create a custom column using isnull , you must
Further reading
combine isnull with another function that accepts boolean values, like case
case.
Organization

People
How Metabase handles nulls
Permissions In Metabase tables, null s are displayed as blank cells. Additionally, for string columns, empty strings and strings containing only whitespace characters will be
displayed as blank as well.
Embedding
The table below shows you examples of the output of isnull .

Configuration
M E TA B AS E S H OWS DATABAS E VALU E IIISSSNNNUUULLLLLL(((VVVAAALLLUUUEEE)))

Tools
null true

Cloud

"" (empty string) false *


Metabase API

" " (whitespace) false


Troubleshooting

Developer guide kitten "kitten" false

Paid features

*In Oracle and Vertica databases, empty strings are treated as nulls instead.

Creating a boolean custom column


To create a custom column using isnull , you must combine isnull with another function. For example, if you want to create a custom column that contains true
when the Discount column is null, and false otherwise, you can use the case expression :
case expression

case(isnull([Discount]), true, false)

Replacing null values with another value


Combine isnull with the case
case expression to replace missing information with something more descriptive:

For example, you can create a new custom column that will contain "Unknown feedback" when the original [Feedback] column is null, and the actual feedback value
when [Feedback] is has a value. The custom expression to do it is:

case(isnull([Feedback]), "Unknown feedback.", [Feedback])

F E EDB AC K CCCAAASSSEEE(((IIISSSNNNUUULLLLLL((([[[FFFEEEEEEDDDBBBAAACCCKKK]]]))),,, """UUUNNNKKKNNNOOOWWWNNN FFFEEEEEEDDDBBBAAACCCKKK...""",,, [[[FFFEEEEEEDDDBBBAAACCCKKK]]])))

null "Unknown feedback."

"" ""

"I like your style." "I like your style."

Accepted data types


DATA T Y PE W ORK S W IT H IIISSSNNNUUULLLLLL

String

Number

Timestamp

Boolean

JSON

Limitations

In Metabase, you must combine isnull with another expression that accepts boolean arguments (i.e., true or false ).

isnull only accepts one value at a time. If you need to deal with blank cells across multiple columns, see the coalesce expression.

If isnull doesn’t seem to do anything to your blank cells, you might have empty strings. Try the isempty
isempty expression instead.

Related functions
This section covers functions and formulas that can be used interchangeably with the Metabase isnull expression, with notes on how to choose the best option for
your use case.

SQL

Spreadsheets

Python

All examples below use the table from the Replacing null values example:

F E EDB AC K CCCAAASSSEEE(((IIISSSNNNUUULLLLLL((([[[FFFEEEEEEDDDBBBAAACCCKKK]]]))),,, """UUUNNNKKKNNNOOOWWWNNN FFFEEEEEEDDDBBBAAACCCKKK...""",,, [[[FFFEEEEEEDDDBBBAAACCCKKK]]])))

null "Unknown feedback."

"" ""

"I like your style." "I like your style."

SQL
In most cases (unless you’re using a NoSQL database), questions created from the query builder are converted into SQL queries that run against your database or
data warehouse.

CASE WHEN Feedback IS NULL THEN "Unknown feedback",


ELSE Feedback END

is equivalent to the Metabase isnull expression:

case(isnull([Feedback]), "Unknown feedback.", [Feedback])

Spreadsheets
Spreadsheet #N/A s are the equivalent of database null s (placeholders for “unknown” or “missing” information).

Assuming our sample feedback column is in a spreadsheet where “Feedback” is in column A, then the formula

=IF(ISNA(A2), "Unknown feedback.", A2)

is equivalent to the Metabase isnull expression:

case(isnull([Feedback]), "Unknown feedback.", [Feedback])

Python
Numpy and pandas use NaN s or NA s instead of null s.

Assuming our sample feedback column is in a dataframe column called df["Feedback"] :

df["Custom Column"] = np.where(df["Feedback"].isnull(), "Unknown feedback.", df["Feedback"])

is equivalent to the Metabase isnull expression:

case(isnull([Feedback]), "Unknown feedback.", [Feedback])

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Combining text from different


Installation Concat columns

concat joins text data (strings) from two or more columns. Accepted data types
Databases
Related functions
S Y NTAX EXAMPL E
Questions
Further reading
concat(value1, value2, ...) concat("Vienna, ", "Austria")
Dashboards

Data modeling Combines two or more strings. “Vienna, Austria”

Actions

Organization

People Combining text from different columns


Permissions CI T Y CO UNT RY LOC AT IO N

Embedding Vienna Austria Vienna, Austria

Configuration
Paris France Paris, France

Tools
Kalamata Greece Kalamata, Greece
Cloud

Metabase API

where Location is a custom column with the expression:


Troubleshooting

Developer guide CONCAT([City], ", ", [Country])

Paid features

Accepted data types


DATA T Y PE W ORK S W IT H CCCOOONNNCCCAAATTT

String

Number

Timestamp

Boolean

JSON

Related functions
This section covers functions and formulas that work the same way as the Metabase concat expression, with notes on how to choose the best option for your use
case.

SQL

Spreadsheets

Python

SQL
In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or
data warehouse.

If our sample data is stored in a relational database:

SELECT
CONCAT(City, ", ", Country) AS "Location"
FROM
richard_linklater_films;

is equivalent to the Metabase concat expression:

concat([City], ", ", [Country])

Spreadsheets
If our sample data is in a spreadsheet where “City” is in column A, and “Country” in column B, we can create a third column “Location” like this,

=CONCATENATE(A2, ", ", B2)

which is equivalent to the Metabase concat expression:

concat([City], ", ", [Country])

Python
Assuming the sample data is in a dataframe column called df,

df["Location"] = df["City"] + ", " + df["Country"]

is the same as the Metabase concat expression:

concat([City], ", ", [Country])

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Syntax
Installation Isempty
How Metabase handles empty
isempty checks whether a value in a string column is an empty string ( "" ) or null. Calling isempty on a non-string column would cause an error. strings and null values
Databases
Creating a boolean custom column
Questions
Syntax Replacing empty strings with
another value
Dashboards
Accepted data types
isempty(text column)
Data modeling Limitations

You can use isempty in custom filters, or as the condition for conditional aggregations CountIf
CountIf and SumIf
SumIf. To create a custom column using isempty , you must Related functions
Actions
combine isempty with another function that accepts boolean values, like case
case. Further reading
Organization

People
How Metabase handles empty strings and null values
Permissions In Metabase, columns with string data types will display blank cells for empty strings, strings of whitespace characters, or null values (if the column is nullable in
your database). The table below shows you examples of the output of isempty .
Embedding
M E TA B AS E S H OWS DATABAS E VALU E IIISSSEEEMMMPPPTTTYYY(((VVVAAALLLUUUEEE)))

Configuration
null true
Tools

"" (empty string) true


Cloud

Metabase API " " (whitespace) false

Troubleshooting
kitten "kitten" false

Developer guide

Paid features

Creating a boolean custom column


To create a custom column using isempty , you must combine isempty with another function. For example, if you want to create a custom column that contains true
when the Feedback column is empty or null, and false otherwise, you can use the case expression :
case expression

case(isempty([Feedback]), true, false)

Replacing empty strings with another value


You can combine isempty with the case
case expression to replace empty strings with something more descriptive.

For example, you can create a new custom column that will contain "No feedback" when the original [Feedback] column is empty or null, and the feedback value
when [Feedback] is has a non-empty value. The custom expression to do it is:

case(isempty([Feedback]), "No feedback.", [Feedback])

F E EDB AC K CCCAAASSSEEE(((IIISSSEEEMMMPPPTTTYYY((([[[FFFEEEEEEDDDBBBAAACCCKKK]]]))),,, """NNNOOO FFFEEEEEEDDDBBBAAACCCKKK...""",,, [[[FFFEEEEEEDDDBBBAAACCCKKK]]])))

"" "No feedback."

null "No feedback."

"I like your style." "I like your style."

Accepted data types


DATA T Y PE W ORK S WIT H IIISSSEEEMMMPPPTTTYYY

String

Number

Timestamp

Boolean

JSON

Limitations

To create a custom column you must combine isempty with another expression that accepts boolean arguments (i.e., true or false ).

isempty only accepts one value at a time. If you need to deal with empty strings from multiple columns, you’ll need to use multiple isempty expressions with the
case expression.

Related functions
This section covers functions and formulas that can be used interchangeably with the Metabase isempty expression, with notes on how to choose the best option for
your use case.

SQL

Spreadsheets

Python

All examples below use the table from the Replacing empty strings example:

F E EDB AC K CCCAAASSSEEE(((IIISSSEEEMMMPPPTTTYYY((([[[FFFEEEEEEDDDBBBAAACCCKKK]]]))),,, """NNNOOO FFFEEEEEEDDDBBBAAACCCKKK...""",,, [[[FFFEEEEEEDDDBBBAAACCCKKK]]])))

"" "No feedback."

null "No feedback."

"I like your style." "I like your style."

SQL
In most cases (unless you’re using a NoSQL database), questions created from the query builder are converted into SQL queries that run against your database or
data warehouse.

CASE WHEN (Feedback = "" OR Feedback IS NULL) THEN "No feedback"


ELSE Feedback END

is equivalent to the Metabase isempty expression:

case(isempty([Feedback]), "No feedback.", [Feedback])

Spreadsheets
If our sample feedback column is in a spreadsheet where “Feedback” is in column A, then the formula

=IF(A2 = "", "Unknown feedback.", A2)

is equivalent to the Metabase isempty expression:

case(isempty([Feedback]), "No feedback.", [Feedback])

Python
Assuming the sample feedback column is in a dataframe column called df["Feedback"] :

df["Custom Column"] = np.where((df["Feedback"] == "") | (df["Feedback"].isnull()), "No feedback.", df["Feedback"])

is equivalent to the Metabase isempty expression:

case(isempty([Feedback]), "No feedback.", [Feedback])

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Searching and cleaning text


Installation Regexextract
Accepted data types
regexextract uses regular expressions (regex) to get a specific part of your text.
Databases Limitations
regexextract is ideal for text that has little to no structure, like URLs or freeform survey responses. If you’re working with strings in predictable formats like SKU
Questions Related functions
numbers, IDs, or other types of codes, check out the simpler substring expression instead.
Further reading
Dashboards Use regexextract to create custom columns with shorter, more readable labels for things like:

Data modeling filter dropdown menus,

chart labels, or
Actions
embedding parameters.

Organization
S Y NTAX EXAMPL E

People
regexextract(text, regular_expression) regexextract("regexextract", "ex(.*)")

Permissions
Gets a specific part of your text using a regular expression. “extract”
Embedding

Configuration

Tools
Searching and cleaning text
Cloud
Let’s say that you have web data with a lot of different URLs, and you want to map each URL to a shorter, more readable campaign name.

Metabase API
U RL CAMPAIGN N AME

Troubleshooting
https://www.metabase.com/docs/?utm_campaign=alice alice

Developer guide
https://www.metabase.com/learn/?utm_campaign=neo neo
Paid features

https://www.metabase.com/glossary/?utm_campaign=candy candy

You can create a custom column Campaign Name with the expression:

regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")

Here, the regex pattern ^[^?#]+\?


^[^?#]+\? matches all valid URL strings. You can replace utm_campaign= with whatever query parameter you like. At the end of the regex
pattern, the capturing group (.*) gets all of the characters that appear after the query parameter utm_campaign= .

Now, you can use Campaign Name in places where you need clean labels, such as filter dropdown menus, charts, and embedding parameters.

Accepted data types


DATA T Y PE W ORK S WIT H RRREEEGGGEEEXXXEEEXXXTTTRRRAAACCCTTT

String

Number

Timestamp

Boolean

JSON

Limitations
Regex can be a dark art. You have been warned.

regexextract is not supported on H2 (including the Metabase Sample Database), SQL Server, and SQLite.

Related functions
This section covers functions and formulas that work the same way as the Metabase regexextract expression, with notes on how to choose the best option for your
use case.

Metabase expressions

substring

Other tools

SQL

Spreadsheets

Python

Substring
Use substring when you want to search text that has a consistent format (the same number of characters, and the same relative order of those characters).

For example, you wouldn’t be able to use substring to get the query parameter from the URL sample data, because the URL paths and the parameter names both
have variable lengths.

But if you wanted to pull out everything after https://www. and before .com , you could do that with either:

substring([URL], 13, 8)

or

regexextract([URL], "^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/.\n]+)")

SQL
When you run a question using the notebook editor, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our sample data is stored in a PostgreSQL database:

SELECT
url,
SUBSTRING(url, '^[^?#]+\?utm_campaign=(.*)') AS campaign_name
FROM follow_the_white_rabbit

is equivalent to the Metabase regexextract expression:

regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")

Spreadsheets
If our sample data is in a spreadsheet where “URL” is in column A, the spreadsheet function

regexextract(A2, "^[^?#]+\?utm_campaign=(.*)")

uses pretty much the same syntax as the Metabase expression:

regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")

Python
Assuming the sample data is in a dataframe column called df ,

df['Campaign Name'] = df['URL'].str.extract(r'^[^?#]+\?utm_campaign=(.*)')

does the same thing as the Metabase regexextract expression:

regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation Substring
Getting a substring from the left
substring extracts part of some text. This function is useful for cleaning up text (or any value with a string data type) that has a consistent format.
Databases Getting a substring from the right
For example, substring should work well on strings like SKU numbers, ISO codes, and standardized email addresses.
Questions Accepted data types

S Y NTAX EXAMPLE Limitations


Dashboards
Related functions
substring(text, position, length) substring("user_id@email.com", 1, 7)
Data modeling Further reading

Actions Extracts part of the text given a starting point (position) and a length (number of characters). “user_id”

Organization

People

Permissions Parameters

Embedding The first character in your string is at position 1.

The length of your substring should always be a positive number.


Configuration

Tools
Getting a substring from the left
Cloud
M IS S I ON I D AGENT

Metabase API
19951113006 006

Troubleshooting
20061114007 007
Developer guide

19640917008 008
Paid features

Agent is a custom column with the expression:

substring([Mission ID], 9, 3)

Getting a substring from the right


Instead of using a number for the position, you’ll use the formula

1 + length([column]) - position_from_right

where position_from_right is the number of characters you want to count from right to left.

M IS S I ON I D AGENT

19951113006 006

20061114007 007

19640917008 008

Here, Agent is a custom column with the expression:

substring([Mission ID], (1 + length([Mission ID]) - 3), 3)

Accepted data types


DATA T Y PE W ORK S WIT H SSSUUUBBBSSSTTTRRRIIINNNGGG

String

Number

Timestamp

Boolean

JSON

Limitations
substring extracts text by counting a fixed number of characters. If you need to extract text based on some more complicated logic, try regexextract
regexextract.

And if you only need to clean up extra whitespace around your text, you can use the trim
trim, ltrim
ltrim, or rtrim
rtrim expressions instead.

Related functions
This section covers functions and formulas that work the same way as the Metabase substring expression, with notes on how to choose the best option for your use
case.

Metabase expressions

regexextract

Other tools

SQL

Spreadsheets

Python

Regexextract
Use regexextract if you need to extract text based on more specific rules. For example, you could get the agent ID with a regex pattern that finds the last occurrence
of “00” (and everything after it):

regexextract([Mission ID], ".+(00.+)$")

should return the same result as

substring([Mission ID], 9, 3)

SQL
When you run a question using the notebook editor, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our sample data is stored in a PostgreSQL database:

SELECT
mission_id,
SUBSTRING(mission_id, 9, 3) AS agent
FROM
this_message_will_self_destruct;

is equivalent to the Metabase substring expression:

substring([Mission ID], 9, 3)

Spreadsheets
If our sample data is in a spreadsheet where “Mission ID” is in column A,

=mid(A2,9,3)

is the same as the Metabase substring expression:

substring([Mission ID], 9, 3)

Python
Assuming the sample data is in a dataframe column called df ,

df['Agent'] = df['Mission ID'].str.slice(8, 11)

does the same thing as the Metabase substring expression:

substring([Mission ID], 9, 3)

Further reading

Custom expressions documentation

Custom expressions tutorial

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation ConvertTimezone
Creating custom report dates
convertTimezone shifts a timestamp into a specified time zone by adding or subtracting the right interval from the timestamp.
Databases Accepted data types
S Y NTAX EXAMPL E
Questions Limitations

Related functions
convertTimezone(column, target, source) convertTimezone("2022-12-28T12:00:00", "Canada/Pacific",
Dashboards
"Canada/Eastern") Further reading

Data modeling

Shifts a timestamp from the source time zone to the target time Returns the value 2022-12-28T09:00:00 , displayed as December 28, 2022 9:00 AM
Actions zone.

Organization

People
Timestamps and time zones are rather nasty to work with (it’s easy to make mistakes, and difficult to catch them), so you should only try to use convertTimezone if
Permissions the interpretation of your data is sensitive to time-based cutoffs.

For example, if you’re tracking user logins over time, you probably won’t run your business differently if some logins get counted on Mondays instead of Tuesdays.
Embedding
However, if you’re using Metabase to do something precise, like your taxes, you (and the government) will probably care a lot more about the difference between
transactions that occurred on Dec 31 vs. Jan 1.
Configuration

Tools
Parameters
Cloud column can be any of:

Metabase API The name of a timestamp column,

a custom expression that returns a timestamp, or


Troubleshooting
a string in the format "YYYY-MM-DD or "YYYY-MM-DDTHH:MM:SS" .
Developer guide
target :

Paid features The name of the time zone you want to assign to your column.

source :

The name of your column’s current time zone.

Required for columns or expressions with the data type timestamp without time zone .

Optional for columns or expressions with the data type timestamp with time zone .

For more info, see Accepted data types.

We support tz database time zone names (such as “Canada/Eastern” instead of “EST”).

Creating custom report dates


Let’s say that you have some time series data that’s stored in one or more time zones (Source Time). You want to create custom reporting dates for a team that lives
in EST.

S OU RC E TI M E T EAM REPO RT T IME (EST )

December 28, 2022, 10:00:00 December 28, 2022, 07:00:00

December 28, 2022, 21:00:00 December 28, 2022, 19:00:00

December 27, 2022, 08:00:00 December 27, 2022, 05:00:00

If Source Time is stored as a timestamp with time zone or a timestamp with offset , you only need to provide the target time zone:

convertTimezone([Source Time], 'EST')

If Source Time is stored as a timestamp without time zone , you must provide the source time zone (which will depend on your database time zone):

convertTimezone([Source Time], 'EST', 'UTC')

It’s usually a good idea to label convertTimezone columns with the name of the target time zone (or add the target time zone to the metadata of a model). We
promise this will make your life easier when someone inevitably asks why the numbers don’t match.

If you’re not getting the results that you expect:

Check if you have the right source time zone.

Ask your database admin about timestamp with time zone vs. timestamp without time zone (for more info, see Accepted data types).

Choosing a source time zone


When you’re doing time zone conversions, make sure you know the source time zone that you’re working with. Different columns (and even different rows) in the
same table, question, or model can be in different “source” time zones.

P OS S IB LE S OURCE
DE S CRI P TI ON EXAMPL E
TI M E ZON E

Client time zone Time zone where an event happened. A web analytics service might capture data in the local time zone of each
person who visited your website.

Database time Time zone metadata that’s been added to It’s a common database practice to store all timestamps in UTC.
zone timestamps in your database.

No time zone Missing time zone metadata Databases don’t require you to store timestamps with time zone metadata.

Metabase report Time zone that Metabase uses to display Metabase can display dates and times in PST, even if the dates and times are
time zone timestamps. stored as UTC in your database.

For example, say you have a table with one row for each person who visited your website. It’s hard to tell, just from looking at December 28, 2022, 12:00 PM ,
whether the “raw” timestamp is:

stored using your database’s time zone (usually UTC),

stored without time zone metadata (for example, if the website visitor is in HKT, then the timestamp December 28, 2022, 12:00 PM might “implicitly” use Hong
Kong time),

displayed in your Metabase report time zone.

For more gory details, see Limitations.

Accepted data types


DATA T Y PE W ORK S W IT H CCCOOONNNVVVEEERRRTTTTTTIIIMMMEEEZZZOOONNNEEE

String

Number

Timestamp

Boolean

JSON

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase.

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

To use convertTimezone without running into errors or pesky undetectable mistakes, you should know that there are a few varieties of timestamp data types:

DATA T YP E DE S C RIPT ION EXAMPL E

timestamp with time zone Knows about location. 2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'

timestamp with offset Knows about the time difference from UTC. 2022-12-28T12:00:00-04:00

timestamp without time zone No time zone info. 2022-12-28T12:00:00

Note that the first part of the timestamp is in UTC (same thing as GMT). The time zone or offset tells you how much time to add or subtract for a given time zone.

convertTimezone will work with all three types of timestamps, but the output of convertTimezone will always be a timestamp without time zone .

Limitations
convertTimezone is currently unavailable for the following databases:

Amazon Athena

Druid

Google Analytics

MongoDB

Presto

SparkSQL

SQLite

Metabase Sample Database

Notes on source time zones


Metabase displays timestamps without time zone or offset information, which is why you have to be so careful about the source time zone when using
convertTimezone .

The Metabase report time zone only applies to timestamp with time zone or timestamp with offset data types. For example:

RAW TI M ES TAM P I N YOU R DATA B A S E DATA TYPE REPORT T IME ZONE DISPLAYED AS

2022-12-28T12:00:00 AT TIME ZONE 'CST' timestamp with time zone ‘Canada/Eastern’ Dec 28, 2022, 7:00 AM

2022-12-28T12:00:00-06:00 timestamp with offset ‘Canada/Eastern’ Dec 28, 2022, 7:00 AM

2022-12-28T12:00:00 timestamp without time zone ‘Canada/Eastern’ Dec 28, 2022, 12:00 AM

The Metabase report time zone will not apply to the output of a convertTimezone expression. For example:

convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central")

will produce a raw timestamp without time zone

2022-12-28T04:00:00

and displayed in Metabase as

Dec 28, 2022, 4:00 AM

If you use convertTimezone on a timestamp without time zone , make sure to use ‘UTC’ as the source time zone, otherwise the expression will shift your
timestamp by the wrong amount. For example, if our timestamp without time zone is only “implied” to be in CST, we should use ‘UTC’ as the source parameter to
get the same result as above.

For example, if we choose ‘CST’ as the source time zone for a timestamp without time zone :

convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central")

we’ll get the raw timestamp without time zone

2022-12-28T10:00:00

displayed in Metabase as

Dec 28, 2022, 10:00 AM

Related functions
This section covers functions and formulas that work the same way as the Metabase convertTimezone expression, with notes on how to choose the best option for
your use case.

SQL

Spreadsheets

Python

SQL
When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our timestamp sample data is a timestamp without time zone stored in a PostgreSQL database:

SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'EST' AS team_report_time_est

is the same as the convertTimezone expression with a source parameter set to ‘UTC’:

convertTimezone([Source Time], "Canada/Eastern", "UTC")

If source_time is a timestamp with time zone or timestamp with offset (for example, in a Snowflake database), then we don’t need to specify a source time
zone in SQL or in Metabase.

SELECT convert_timezone('America/Toronto', source_time) AS team_report_time_est

is the same as

convertTimezone([Source Time], "Canada/Eastern")

Remember that the time zone names depend on your database. For example, Snowflake doesn’t accept most time zone abbreviations (like EST).

Spreadsheets
If our timestamp sample data is in a spreadsheet where “Source Time” is in column A, we can change it to EST by subtracting the hours explicitly:

A1 - TIME(5, 0, 0)

to get the same result as

convertTimezone([Client Time], "Canada/Eastern")

Python
If the timestamp sample data is stored in a pandas dataframe, you could convert the Source Time column to a timestamp object with time zone first(basically
making a timestamp without time zone into a timestamp with time zone ), then use tz_convert to change the time zone to EST:

df['Source Time (UTC)'] = pd.to_timestamp(df['Source Time'], utc=True)


df['Team Report Time (EST)'] = df['Source Time (UTC)'].dt.tz_convert(tz='Canada/Eastern')

to do the same thing as a nested convertTimezone expression

convertTimezone(convertTimezone([Source Time], "UTC"), "Canada/Eastern", "UTC")

Further reading

Custom expressions documentation

Custom expressions tutorial

Time series analysis

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation DatetimeAdd
Calculating an end date
datetimeAdd takes a datetime value and adds some unit of time to it. This function is useful when you’re working with time series data that’s marked by a “start” and
Databases
an “end”, such as sessions or subscriptions data. Checking if the current datetime is
within an interval
Questions
S Y NTAX EXAMPL E Accepted data types

Dashboards Limitations
datetimeAdd(column, amount, unit) datetimeAdd("2021-03-25", 1, "month")
Related functions
Data modeling
Takes a timestamp or date value and adds the specified number of time units to it. 2021-04-25 Further reading
Actions

Organization

People

Parameters
Permissions
column can be any of:

Embedding
The name of a timestamp column,

Configuration a custom expression that returns a datetime, or

a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS" (as shown in the example above).
Tools
unit can be any of:
Cloud
“year”

Metabase API “quarter”

“month”
Troubleshooting
“day”
Developer guide “hour”

“minute”
Paid features
“second”

“millisecond”

amount :

A whole number or a decimal number.

May be a negative number: datetimeAdd("2021-03-25", -1, "month") will return 2021-04-25 .

Calculating an end date


Let’s say you’re a coffee connoisseur, and you want to keep track of the freshness of your beans:

CO F F EE O PEN ED ON FINISH BY

DAK Honey Dude October 31, 2022 November 14, 2022

NO6 Full City Espresso November 7, 2022 November 21, 2022

Ghost Roaster Giakanja November 27, 2022 December 11, 2022

Here, Finish By is a custom column with the expression:

datetimeAdd([Opened On], 14, 'day')

Checking if the current datetime is within an interval


Let’s say you want to check if today’s date falls between a start date and an end date. Assume “today” is December 1, 2022.

CO F F EE O PENED ON FINISH BY ST ILL FR ES H TO DAY

DAK Honey Dude October 31, 2022 November 14, 2022 No

NO6 Full City Espresso November 7, 2022 November 21, 2022 No

Ghost Roaster Giakanja November 27, 2022 December 11, 2022 Yes

Finish By is a custom column with the expression:

datetimeAdd([Opened On], 14, 'day')

Still Fresh Today uses case to check if the current date (now) is between the dates in Opened On and Finish By:

case(between(now, [Opened On], [Finish By]), "Yes", "No")

Accepted data types


DATA T Y PE W ORK S WIT H DDDAAATTTEEETTTIIIMMMEEEAAADDDDDD

String

Number

Timestamp

Boolean

JSON

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see
Timezones.

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

Limitations
If you’re using MongoDB, datetimeAdd will only work on versions 5 and up.

Related functions
This section covers functions and formulas that work the same way as the Metabase datetimeAdd expression, with notes on how to choose the best option for your
use case.

Metabase expressions

datetimeSubtract

Other tools

SQL

Spreadsheets

Python

datetimeSubtract
datetimeSubtract and datetimeAdd are interchangeable, since you can use a negative number for amount . It’s generally a good idea to avoid double negatives (such
as subtracting a negative number).

datetimeSubtract([Opened On], -14, "day")

does the same thing as

datetimeAdd([Opened On], 14, "day")

SQL
When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our coffee sample data is stored in a PostgreSQL database:

SELECT opened_on + INTERVAL '14 days' AS finish_by


FROM coffee

is equivalent to the Metabase datetimeAdd expression:

datetimeAdd([Opened On], 14, "day")

Spreadsheets
If our coffee sample data is in a spreadsheet where “Opened On” is in column A with a date format, the spreadsheet function

A:A + 14

produces the same result as

datetimeAdd([Opened On], 14, "day")

Most spreadsheet tools require use different functions for different time units (for example, you’d use a different function to add “months” to a date). datetimeAdd
makes it easy for you to convert all of those functions to a single consistent syntax.

Python
Assuming the coffee sample data is in a pandas dataframe column called df , you can import the datetime module and use the timedelta function:

df['Finish By'] = df['Opened On'] + datetime.timedelta(days=14)

is equivalent to

datetimeAdd([Opened On], 14, "day")

Further reading

Custom expressions documentation

Custom expressions tutorial

Time series analysis

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Like so many others, we use cookies to improve your experience on this website. We assume you're OK with it, but you can opt out if you want. Settings Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Parameters
Installation DatetimeSubtract
Calculating a start date
datetimeSubtract takes a datetime value and subtracts some unit of time from it. You might want to use this function when working with time series data that’s
Databases
marked by a “start” and an “end”, such as sessions or subscriptions data. Checking if the current datetime is
within an interval
Questions
S Y NTAX EXAMPL E Accepted data types

Dashboards Limitations
datetimeSubtract(column, amount, unit) datetimeSubtract("2021-03-25", 1, "month")
Related functions
Data modeling
Takes a timestamp or date value and subtracts the specified number of time units from it. 2021-02-25 Further reading
Actions

Organization

People

Parameters
Permissions
column can be any of:

Embedding
The name of a timestamp column,

Configuration a custom expression that returns a datetime, or

a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS" (as shown in the example above).
Tools
unit can be any of:
Cloud
“year”

Metabase API “quarter”

“month”
Troubleshooting
“day”
Developer guide “hour”

“minute”
Paid features
“second”

“millisecond”

amount :

A whole number or a decimal number.

May be a negative number: datetimeSubtract("2021-03-25", -1, "month") will return 2021-04-25 .

Calculating a start date


Let’s say you’re planning a fun night out. You know it takes 30 minutes to get from place to place, and you need to figure out what time you have to leave to get to
each of your reservations:

E VE N T A RRI V E B Y DEPART AT

Drinks November 12, 2022 6:30 PM November 12, 2022 6:00 PM

Dinner November 12, 2022 8:00 PM November 12, 2022 7:30 PM

Dancing November 13, 2022 12:00 AM November 12, 2022 11:30 PM

Here, Depart At is a custom column with the expression:

datetimeSubtract([Arrive By], 30, "minute")

Checking if the current datetime is within an interval


Say you want to check if the current datetime falls between a start date and an end date. Assume the “current” datetime is November 12, 7:45 PM.

E VE N T A RRI V E B Y DEPART AT O N MY WAY

Drinks November 12, 2022 6:30 PM November 12, 2022 6:00 PM No

Dinner November 12, 2022 8:00 PM November 12, 2022 7:30 PM Yes

Dancing November 13, 2022 12:00 AM November 12, 2022 11:30 PM No

Depart At is a custom column with the expression:

datetimeSubtract([Arrive By], 30, "minute")

On My Way uses case to check if the current datetime (now) is between the datetimes in Arrive By and Depart At:

case(between(now, [Depart At], [Arrive By]), "Yes", "No")

Accepted data types


DATA T Y PE W ORK S WIT H DDDAAATTTEEETTTIIIMMMEEESSSUUUBBBTTTRRRAAACCCTTT

String

Number

Timestamp

Boolean

JSON

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see
Timezones.

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

Limitations
If you’re using MongoDB, datetimeSubtract will only work on versions 5 and up.

Related functions
This section covers functions and formulas that work the same way as the Metabase datetimeSubtract expression, with notes on how to choose the best option for
your use case.

Metabase expressions

datetimeAdd

Other tools

SQL

Spreadsheets

Python

datetimeAdd
datetimeSubtract and datetimeAdd are interchangeable, since you can use a negative number for amount . We could use either expression for our events example,
but you should try to avoid “double negatives” (such as subtracting a negative number).

datetimeAdd([Arrive By], -30, "minute")

does the same thing as

datetimeSubtract([Arrive By], 30, "minute")

SQL
When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query
against your database to get your results.

If our events sample data is stored in a PostgreSQL database:

SELECT arrive_by - INTERVAL '30 minutes' AS depart_at


FROM events

is equivalent to the Metabase datetimeSubtract expression:

datetimeSubtract([Arrive By], 30, "minute")

Spreadsheets
Assuming the events sample data is in a spreadsheet where “Arrive By” is in column A with a datetime format, the spreadsheet function

A:A - 30/(60*24)

produces the same result as

datetimeSubtract([Arrive By], 30, "minute")

Most spreadsheets require you to use different calculations for different time units (for example, you’d need to use a different calculation to subtract “days” from a
date). datetimeSubtract makes it easy for you to convert all of those functions to a single consistent syntax.

Python
If our events sample data is in a pandas dataframe column called df , you can import the datetime module and use the timedelta function:

df['Depart At'] = df['Arrive By'] - datetime.timedelta(minutes=30)

is equivalent to

datetimeSubtract([Arrive By], 30, "minute")

Further reading

Custom expressions documentation

Custom expressions tutorial

Time series analysis

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies
Upcoming Tour of Metabase advanced Register Now ×
Product Features Documentation Resources Pricing Log in Get started

v0.49 Questions On this page

Creating conditional logic using the


Installation Now current date or time

now returns the current datetime using your Metabase report timezone. Data types
Databases
Limitations
Questions
Creating conditional logic using the current date or time Related functions

Dashboards Further reading


Let’s say you have some project data, and you want to add a status column for each task. We’ll assume today’s date and time is November 22, 2022, 12:00:00.

Data modeling TA S K S TA RT DEADLINE STAT US

Actions
Draft November 1, 2022, 12:00:00 November 30, 2022, 12:00:00 In progress

Organization
Review November 15, 2022, 12:00:00 November 19, 2022, 12:00:00 Needs extension
People

Edit November 22, 2022, 12:00:00 November 22, 2022, 12:00:00 DUE RIGHT NOW!
Permissions

Embedding

Configuration To mark a task in progress, you’d use the expression:

Tools
now >= [Start] AND now < [Deadline]

Cloud
To check if you need to ask for an extension:
Metabase API

now >= [Start] AND now >= [Deadline]


Troubleshooting

Developer guide
If you’re looking for an adrenaline rush (and you have real-time data), you can flag the tasks that are due right this second:

Paid features
now = [Deadline]

To set up the Status column that combines all three situations above, you’d wrap everything in a case expression:

case(now >= [Start] AND now < [Deadline], "In progress",


now >= [Start] AND now >= [Deadline], "Needs extension",
now = [Deadline], "DUE RIGHT NOW!")

Data types
DATA T Y PE RET URNED BY NNNOOOWWW

String

Number

Timestamp

Boolean

JSON

now returns a timestamp with time zone if time zones are supported by your database, otherwise now returns a timestamp without time zone .

For more info about the way these data types behave in Metabase, see Timezones.

Limitations
now might not actually be now (in your local time) if you don’t live in the same timezone as your Metabase report time zone.

If you need to compare now to a column in a different time zone, use convertTimezone to shift both columns into the same time zone. For example:

convertTimezone(now, 'UTC', <report timezone>) >= convertTimezone([Deadline], 'UTC', <source time zone>)

Related functions
Different ways to do the same thing, because while you’d love to use custom expressions more, now’s just not the time.

SQL

Spreadsheets

Python

SQL
When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query
against your database to get your results.

By default, now uses your Metabase’s report time zone. If your admin hasn’t set a report time zone, now will use your database’s time zone.

Say you’re using a Postgres database. If your Metabase report time zone is set to EST, you’ll get now in EST:

SELECT CURRENT_TIMESTAMP AT TIME ZONE 'EST'

If you don’t have a report time zone, you’ll get now in the Postgres database’s time zone (typically UTC):

SELECT CURRENT_TIME

Spreadsheets
The spreadsheet function NOW() gets the current date and time in your operating system’s time zone (the time that’s on your computer or mobile device).

Python
You can use pd.Timestamp.now() using the pandas module. This will give you a Timestamp object with the current date and time in your operating system’s time
zone.

Further reading

Custom expressions documentation

Custom expressions tutorial

Time series analysis

Read docs for other versions of Metabase.

Did this article help you? Yes No

Want to improve these docs? Propose a change.

Subscribe to our newsletter


Email address Sign up
Stay in touch with updates and news from Metabase. No spam, ever.

Product Use Cases Features Company Resources

Watch Demo Self-Service Business Analytics Query Builder Jobs We're hiring! Case Studies

Data Sources Embedded Analytics Drill Through Privacy Policy Blog

Security Collections Terms of Service Learn


Metabase Plans
Cloud Usage analytics New License Community Stories
Starter and Open Source
Roadmap Analytics dashboards Brand Guidelines Data and Business Intelligence
Pro
Glossary
What's New SQL editor
Enterprise Support
Partners
Sandboxing
Pricing Documentation
The Startup's Guide to Financial
Models
Plans Help Modeling

Permissions
Open Source Professional Services The 2023 Metabase Community

CSV upload Data Stack Report


Onboarding New

More Resources
Status

Github NaNk

© Metabase 2024

Accept cookies

You might also like