What do common formulas look like in SQL?
Each one was converted by the engine and run both ways on the 10 sample rows.
How does an IF become a CASE?
Tableau
IF [Profit] > 0 THEN "Gain" ELSE "Loss" END
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
SELECT
(CASE WHEN ("Profit" > 0.0) THEN 'Gain' ELSE 'Loss' END) AS result
FROM input
| Profit | Tableau | SQL |
|---|
| 18 | Gain | Gain |
| −24 | Loss | Loss |
| 12 | Gain | Gain |
| 40 | Gain | Gain |
| 90 | Gain | Gain |
| Loss | Loss |
| −15 | Loss | Loss |
| 9 | Gain | Gain |
| 4 | Gain | Gain |
| 102 | Gain | Gain |
SQL notes and traps for each function: IF
How do I count weeks between dates like Tableau?
Tableau
DATEDIFF('week', [Order Date], #2024-06-01#)
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
SELECT
CAST((floor((date_diff('day', DATE '1970-01-01', DATE '2024-06-01') + 4) / 7.0) - floor((date_diff('day', DATE '1970-01-01', CAST("Order Date" AS DATE)) + 4) / 7.0)) AS BIGINT) AS result
FROM input
| Order Date | Tableau | SQL |
|---|
| 2024-01-05 | 21 | 21 |
| 2024-01-19 | 19 | 19 |
| 2024-02-02 | 17 | 17 |
| 2024-02-14 | 15 | 15 |
| 2024-03-03 | 12 | 12 |
| 2024-03-21 | 10 | 10 |
| 2024-04-08 | 7 | 7 |
| 2024-04-30 | 4 | 4 |
| 2024-05-12 | 2 | 2 |
| 2024-06-01 | 0 | 0 |
SQL notes and traps for each function: DATEDIFF
How does ZN with a division translate?
Tableau
ZN([Profit]) / [Sales]
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
SELECT (coalesce("Profit", 0) / NULLIF("Sales", 0)) AS result
FROM input
| Sales | Profit | Tableau | SQL |
|---|
| 120 | 18 | 0.15 | 0.15 |
| 300 | −24 | −0.08 | −0.08 |
| 80 | 12 | 0.15 | 0.15 |
| 200 | 40 | 0.2 | 0.2 |
| 450 | 90 | 0.2 | 0.2 |
| 60 | | 0 | 0 |
| 150 | −15 | −0.1 | −0.1 |
| 90 | 9 | 0.1 | 0.1 |
| 40 | 4 | 0.1 | 0.1 |
| 510 | 102 | 0.2 | 0.2 |
SQL notes and traps for each function: ZN
What is DATETRUNC by quarter in SQL?
Tableau
DATETRUNC('quarter', [Order Date])
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
SELECT
CAST(date_trunc('quarter', "Order Date") AS DATE) AS result
FROM input
| Order Date | Tableau | SQL |
|---|
| 2024-01-05 | 2024-01-01 | 2024-01-01 |
| 2024-01-19 | 2024-01-01 | 2024-01-01 |
| 2024-02-02 | 2024-01-01 | 2024-01-01 |
| 2024-02-14 | 2024-01-01 | 2024-01-01 |
| 2024-03-03 | 2024-01-01 | 2024-01-01 |
| 2024-03-21 | 2024-01-01 | 2024-01-01 |
| 2024-04-08 | 2024-04-01 | 2024-04-01 |
| 2024-04-30 | 2024-04-01 | 2024-04-01 |
| 2024-05-12 | 2024-04-01 | 2024-04-01 |
| 2024-06-01 | 2024-04-01 | 2024-04-01 |
SQL notes and traps for each function: DATETRUNC
What does a profit ratio look like per region?
Tableau
SUM([Profit]) / SUM([Sales])
In the view: Region
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
WITH "marks" AS (
SELECT "Region" COLLATE NOCASE AS "Region"
FROM input
GROUP BY "Region"
), "per_mark" AS (
SELECT
"Region" COLLATE NOCASE AS "Region",
(sum("Profit") / NULLIF(sum("Sales"), 0)) AS "result"
FROM input
GROUP BY "Region"
)
SELECT m."Region" AS "Region", o1."result" AS "result"
FROM "marks" m LEFT JOIN "per_mark" o1 ON m."Region" IS NOT DISTINCT FROM o1."Region"
ORDER BY m."Region"
Text compares with COLLATE NOCASE because Tableau compares text without regard to case. Drop it if your data is all one case.
| Region | Tableau | SQL |
|---|
| East | 0.01 | 0.01 |
| North | 0.19 | 0.19 |
| South | −0.03 | −0.03 |
| West | 0.18 | 0.18 |
SQL notes and traps for each function: SUM
How does a FIXED level of detail become SQL?
Tableau
{ FIXED [Region] : SUM([Sales]) }
In the view: Region
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
WITH "lod_0" AS (
SELECT
"Region" COLLATE NOCASE AS "lod_key_0",
sum("Sales") AS "value"
FROM input
GROUP BY "lod_key_0"
), "rows_1" AS (
SELECT b.*, l."value" AS "lod_a81fe6"
FROM input b LEFT JOIN "lod_0" l ON b."Region" COLLATE NOCASE IS NOT DISTINCT FROM l."lod_key_0"
), "marks" AS (
SELECT "Region" COLLATE NOCASE AS "Region"
FROM "rows_1"
GROUP BY "Region"
), "per_mark" AS (
SELECT
"Region" COLLATE NOCASE AS "Region",
MIN("lod_a81fe6") AS "result"
FROM "rows_1"
GROUP BY "Region"
)
SELECT m."Region" AS "Region", o1."result" AS "result"
FROM "marks" m LEFT JOIN "per_mark" o1 ON m."Region" IS NOT DISTINCT FROM o1."Region"
ORDER BY m."Region"
Text compares with COLLATE NOCASE because Tableau compares text without regard to case. Drop it if your data is all one case.
| Region | Tableau | SQL |
|---|
| East | 500 | 500 |
| North | 550 | 550 |
| South | 240 | 240 |
| West | 710 | 710 |
SQL notes and traps for each function: SUM FIXED
What is COUNTD in SQL?
Tableau
COUNTD([Customer])
In the view: Category
✓ Run on 10 rows: this SQL returns the same values as the Tableau formula.
SQL (DuckDB)
WITH "marks" AS (
SELECT "Category" COLLATE NOCASE AS "Category"
FROM input
GROUP BY "Category"
), "per_mark" AS (
SELECT
"Category" COLLATE NOCASE AS "Category",
count(DISTINCT lower("Customer" COLLATE NOCASE)) AS "result"
FROM input
GROUP BY "Category"
)
SELECT m."Category" AS "Category", o1."result" AS "result"
FROM "marks" m LEFT JOIN "per_mark" o1 ON m."Category" IS NOT DISTINCT FROM o1."Category"
ORDER BY m."Category"
Text compares with COLLATE NOCASE because Tableau compares text without regard to case. Drop it if your data is all one case.
| Category | Tableau | SQL |
|---|
| Furniture | 3 | 3 |
| Office | 3 | 3 |
| Technology | 4 | 4 |
SQL notes and traps for each function: COUNTD
What do people ask about converting Tableau to SQL?
Which SQL does it write?
DuckDB SQL that reads a table named input. Most of it runs unchanged on Postgres. For Snowflake and BigQuery, each function's reference page gives the dialect notes.
Does it handle level of detail expressions?
Yes. FIXED, INCLUDE and EXCLUDE become common table expressions at the grain they ask for, joined back to the marks of the view you tick.
What about table calculations like RUNNING_SUM or RANK?
Those run over the marks of a view in a set order, so the converter shows the Tableau result and links each function's page, which gives the window-function SQL.
Why does the SQL say COLLATE NOCASE?
Tableau compares text without regard to case, so east and East are one region. The collation keeps that behaviour in SQL.
Is my file uploaded?
No. The engine and DuckDB run in your browser tab; your CSV never leaves your device.