Bird
Raised Fist0
dbtdata~20 mins

Macros for reusable SQL logic in dbt - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Macro Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a simple macro call in dbt
Given the following dbt macro and model SQL, what is the output SQL after compilation?
dbt
{% macro filter_active_users() %}
  WHERE status = 'active'
{% endmacro %}

SELECT * FROM users {{ filter_active_users() }}
ASELECT * FROM users WHERE status = 'inactive'
BSELECT * FROM users WHERE status = active
CSELECT * FROM users WHERE status = 'active'
DSELECT * FROM users
Attempts:
2 left
💡 Hint
Remember that the macro inserts the exact WHERE clause with the string 'active' in quotes.
🧠 Conceptual
intermediate
1:30remaining
Purpose of macros in dbt
What is the main purpose of using macros in dbt projects?
ATo visualize data in dashboards
BTo create reusable SQL snippets that can be called multiple times to avoid repetition
CTo schedule dbt runs automatically
DTo store data permanently in the database
Attempts:
2 left
💡 Hint
Think about how macros help with writing SQL code efficiently.
🔧 Debug
advanced
2:00remaining
Identify the error in this macro usage
What error will occur when running this dbt model code?
dbt
{% macro get_date_filter(date_col) %}
  WHERE {{ date_col }} > '2023-01-01'
{% endmacro %}

SELECT * FROM sales {{ get_date_filter() }}
ATypeError: get_date_filter() missing 1 required positional argument: 'date_col'
BSyntaxError: Unexpected token in macro
CNo error, runs successfully
DRuntimeError: Undefined variable date_col
Attempts:
2 left
💡 Hint
Check if the macro is called with the required argument.
❓ data_output
advanced
2:30remaining
Resulting SQL from nested macros
Given these macros and model code, what is the final compiled SQL?
dbt
{% macro base_filter() %}
  status = 'active'
{% endmacro %}

{% macro full_filter() %}
  WHERE {{ base_filter() }} AND created_at > '2023-01-01'
{% endmacro %}

SELECT * FROM users {{ full_filter() }}
ASELECT * FROM users WHERE status = 'active' AND created_at > '2023-01-01'
BSELECT * FROM users WHERE status = active AND created_at > '2023-01-01'
CSELECT * FROM users WHERE status = 'active' OR created_at > '2023-01-01'
DSELECT * FROM users WHERE created_at > '2023-01-01'
Attempts:
2 left
💡 Hint
Macros can call other macros and insert their code exactly where called.
🚀 Application
expert
3:00remaining
Using macros to dynamically generate SQL conditions
You want to create a macro that accepts a list of columns and generates a SQL condition checking if any of those columns are NULL. Which macro code produces the correct SQL condition for columns ['col1', 'col2', 'col3']?
dbt
{% macro null_check(cols) %}
  {{- cols | map('string') | join(' IS NULL OR ') }} IS NULL
{% endmacro %}

SELECT * FROM table WHERE {{ null_check(['col1', 'col2', 'col3']) }}
Acol1, col2, col3 IS NULL
BIS NULL col1 OR IS NULL col2 OR IS NULL col3
Ccol1 IS NULL AND col2 IS NULL AND col3 IS NULL
Dcol1 IS NULL OR col2 IS NULL OR col3 IS NULL
Attempts:
2 left
💡 Hint
Think about how to join column names with ' IS NULL OR ' and add ' IS NULL' only once at the end.

Practice

(1/5)
1. What is the main purpose of using macros in dbt?
easy
A. To create visualizations from data
B. To store data permanently in the database
C. To reuse SQL code and make it easier to maintain
D. To write Python scripts inside dbt

Solution

  1. Step 1: Understand what macros do

    Macros are reusable pieces of SQL code that help avoid repetition.
  2. Step 2: Identify the main benefit

    Using macros makes SQL cleaner and easier to maintain by reusing code.
  3. Final Answer:

    To reuse SQL code and make it easier to maintain -> Option C
  4. Quick Check:

    Macros = reusable SQL code [OK]
Hint: Macros = reusable SQL snippets for cleaner code [OK]
Common Mistakes:
  • Thinking macros store data
  • Confusing macros with visualization tools
  • Assuming macros run Python code
2. Which of the following is the correct way to define a macro in dbt?
easy
A. {% macro my_macro() %} SELECT * FROM table {% endmacro %}
B. CREATE MACRO my_macro AS SELECT * FROM table;
C. def my_macro(): SELECT * FROM table
D. macro my_macro() { SELECT * FROM table }

Solution

  1. Step 1: Recall dbt macro syntax

    dbt macros use Jinja templating with {% macro %} and {% endmacro %} tags.
  2. Step 2: Match syntax to options

    {% macro my_macro() %} SELECT * FROM table {% endmacro %} correctly uses Jinja syntax for defining a macro.
  3. Final Answer:

    {% macro my_macro() %} SELECT * FROM table {% endmacro %} -> Option A
  4. Quick Check:

    dbt macros use {% macro %} ... {% endmacro %} [OK]
Hint: Look for {% macro %} and {% endmacro %} tags [OK]
Common Mistakes:
  • Using SQL CREATE MACRO syntax (not dbt)
  • Writing Python function syntax
  • Using curly braces without Jinja tags
3. Given this macro definition:
{% macro select_active_users() %}
SELECT * FROM users WHERE active = true
{% endmacro %}

What will be the output SQL of this dbt model?
SELECT id, name FROM ({{ select_active_users() }})
medium
A. SELECT id, name FROM {{ select_active_users() }}
B. SELECT id, name FROM users WHERE active = true
C. Error: Macro call syntax incorrect
D. SELECT id, name FROM (SELECT * FROM users WHERE active = true)

Solution

  1. Step 1: Understand macro expansion

    The macro returns the SQL: SELECT * FROM users WHERE active = true.
  2. Step 2: Substitute macro call in model SQL

    The model SQL becomes: SELECT id, name FROM (SELECT * FROM users WHERE active = true)
  3. Final Answer:

    SELECT id, name FROM (SELECT * FROM users WHERE active = true) -> Option D
  4. Quick Check:

    Macro expands SQL inside parentheses [OK]
Hint: Macros insert SQL code where called [OK]
Common Mistakes:
  • Forgetting parentheses around macro SQL
  • Thinking macro returns table name only
  • Using macro call without {{ }}
4. Identify the error in this macro definition:
{% macro get_orders() %}
SELECT * FROM orders
medium
A. Macro name cannot have underscores
B. Missing {% endmacro %} tag to close the macro
C. SELECT statement must be inside double quotes
D. Macro cannot return SELECT statements

Solution

  1. Step 1: Check macro syntax

    Macros must start with {% macro %} and end with {% endmacro %} tags.
  2. Step 2: Identify incorrect closing tag

    The macro incorrectly uses instead of {% endmacro %}.
  3. Final Answer:

    Missing {% endmacro %} tag to close the macro -> Option B
  4. Quick Check:

    Macro must end with {% endmacro %} [OK]
Hint: Always close macros with {% endmacro %} [OK]
Common Mistakes:
  • Using HTML-like closing tags
  • Thinking underscores are invalid
  • Believing SELECT needs quotes in macros
5. You want to create a macro that accepts a table name and a column name, then returns SQL to count distinct values in that column. Which macro definition correctly achieves this?
hard
A. {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT {{ column }}) FROM {{ table }} {% endmacro %}
B. {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT column) FROM table {% endmacro %}
C. {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT '{{ column }}') FROM '{{ table }}' {% endmacro %}
D. {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT $column) FROM $table {% endmacro %}

Solution

  1. Step 1: Understand macro parameters usage

    Parameters must be inserted with {{ }} to inject SQL identifiers.
  2. Step 2: Check each option for correct syntax

    {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT {{ column }}) FROM {{ table }} {% endmacro %} correctly uses {{ column }} and {{ table }} without quotes, so SQL identifiers are injected properly.
  3. Final Answer:

    {% macro count_distinct(table, column) %} SELECT COUNT(DISTINCT {{ column }}) FROM {{ table }} {% endmacro %} -> Option A
  4. Quick Check:

    Use {{ }} to insert parameters as SQL code [OK]
Hint: Use {{ }} to insert macro parameters in SQL [OK]
Common Mistakes:
  • Putting parameters inside quotes (makes them strings)
  • Using $variable syntax (not Jinja)
  • Not wrapping parameters with {{ }}
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard