La solicitud

De Jordan Reyes, Director de Marketing
Tu objetivo
Para 2025, devuelve una fila por canal de marketing y mes con: channel, month (el primer día del mes, como DATE), spend (total de marketing_spend.amount, redondeado a 2), conversions (web_sessions con converted = true cuyo source es ese canal) y cost_per_conversion (spend dividido entre conversions, redondeado a 2, NULL cuando conversions es 0). Ordena por channel y luego por month.
- Lee de la tabla
web_sessionspendiente - Lee de la tabla
marketing_spendpendiente - Muestra exactamente
channelmonthspendconversionscost_per_conversionpendiente
Tu consulta
Cargando el editor…
Solución de referencia
| session_id | customer_id | started_at | device | source |
|---|---|---|---|---|
| 1 | NULL | 2023-01-01 23:02:24 | mobile | paid |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid |
| 3 | NULL | 2023-01-01 16:55:46 | desktop | direct |
| 4 | NULL | 2023-01-01 12:43:28 | mobile | organic |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Jordan, y por qué
Tablas
Datos de la tienda Harbor & Pine, listos para consultar.
web_sessions40,000 filas · 7 columnas
session_idintegercustomer_idintegerstarted_attimestampdevicevarcharsourcevarcharpages_viewedintegerconvertedboolean
| session_id | customer_id | started_at | device | source | pages_viewed | converted |
|---|---|---|---|---|---|---|
| 1 | NULL | 2023-01-01 23:02:24 | mobile | paid | 1 | false |
| 2 | 18 | 2023-01-01 15:07:49 | desktop | paid | 1 | false |
| 3 | NULL | 2023-01-01 16:55:46 | desktop | direct | 7 | false |
| 4 | NULL | 2023-01-01 12:43:28 | mobile | organic | 3 | false |
| 5 | NULL | 2023-01-01 13:06:21 | mobile | social | 2 | false |
marketing_spend3,276 filas · 3 columnas
spend_datedatechannelvarcharamountdecimal
| spend_date | channel | amount |
|---|---|---|
| 2023-01-01 | paid | 492.99 |
| 2023-01-01 | 37.38 | |
| 2023-01-01 | social | 200.53 |
| 2023-01-02 | paid | 709.13 |
| 2023-01-02 | 64.13 |
customers2,018 filas · 9 columnas
customer_idintegerfirst_namevarcharlast_namevarcharemailvarcharcityvarcharstatevarcharsignup_datedatesegmentvarcharreferral_sourcevarchar
| customer_id | first_name | last_name | city | state | signup_date | segment | referral_source | |
|---|---|---|---|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco | CA | 2022-06-02 | consumer | search |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta | GA | 2022-06-02 | consumer | NULL |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles | CA | 2022-06-04 | business | NULL |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle | WA | 2022-06-06 | business | |
| 5 | Kyle | Jimenez | kjimenez27@yahoo.com | Indianapolis | IN | 2022-06-07 | consumer | NULL |
products120 filas · 8 columnas
product_idintegernamevarcharcategoryvarcharsubcategoryvarcharunit_pricedecimalunit_costdecimallaunched_ondateis_activeboolean
| product_id | name | category | subcategory | unit_price | unit_cost | launched_on | is_active |
|---|---|---|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 | NULL | 2023-09-11 | true |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 | 503.50 | 2024-05-16 | true |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 | 429.87 | 2023-05-27 | true |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 | 214.70 | 2022-12-20 | true |
| 105 | Avery Leather Bed Frame | Furniture | Beds | 449.00 | 232.70 | 2021-08-31 | true |
orders12,000 filas · 7 columnas
order_idintegercustomer_idintegerorder_datetimestampstatusvarcharchannelvarcharshipping_feedecimalcoupon_codevarchar
| order_id | customer_id | order_date | status | channel | shipping_fee | coupon_code |
|---|---|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web | 0.00 | NULL |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web | 0.00 | NULL |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace | 4.99 | WELCOME10 |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace | 4.99 | WELCOME10 |
| 1005 | 82 | 2023-01-02 11:43:36 | completed | web | 0.00 | WELCOME10 |
order_items30,338 filas · 6 columnas
order_item_idintegerorder_idintegerproduct_idintegerquantityintegerunit_pricedecimaldiscount_pctdecimal
| order_item_id | order_id | product_id | quantity | unit_price | discount_pct |
|---|---|---|---|---|---|
| 1 | 1001 | 121 | 9 | 31.99 | 0.00 |
| 2 | 1001 | 154 | 3 | 11.99 | 0.00 |
| 3 | 1002 | 154 | 4 | 11.99 | 0.00 |
| 4 | 1002 | 194 | 1 | 149.00 | 0.00 |
| 5 | 1002 | 193 | 2 | 19.99 | 0.00 |
returns1,673 filas · 5 columnas
return_idintegerorder_item_idintegerreturned_ondatereasonvarcharrefund_amountdecimal
| return_id | order_item_id | returned_on | reason | refund_amount |
|---|---|---|---|---|
| 1 | 14 | 2023-01-10 | damaged | 83.69 |
| 2 | 42 | 2023-01-10 | wrong_item | 19.99 |
| 3 | 105 | 2023-01-14 | wrong_item | 10.99 |
| 4 | 24 | 2023-01-16 | changed_mind | 26.99 |
| 5 | 126 | 2023-01-16 | late | 20.99 |
employees60 filas · 8 columnas
employee_idintegerfirst_namevarcharlast_namevarchardepartmentvarchartitlevarcharmanager_idintegerhire_datedatesalaryinteger
| employee_id | first_name | last_name | department | title | manager_id | hire_date | salary |
|---|---|---|---|---|---|---|---|
| 1 | Catherine | Hale | Executive | Chief Executive Officer | NULL | 2016-03-01 | 285000 |
| 2 | Robert | Kim | Executive | Chief Operating Officer | 1 | 2017-01-09 | 235000 |
| 3 | Megan | Collins | Sales | Head of Sales | 1 | 2018-04-16 | 172000 |
| 4 | Chloe | Gutierrez | Sales | Account Executive | 3 | 2020-01-21 | 72000 |
| 5 | Frank | Bell | Sales | Account Executive | 3 | 2023-05-21 | 73000 |
La lección
Las tasas son divisiones, y un denominador puede ser cero: un canal sin conversiones, un día sin pedidos,
un producto nuevo sin ventas. Lo que pasa después depende de la base de datos. Postgres, SQL Server y
Snowflake detienen toda la consulta con un error de “división entre cero”. DuckDB devuelve Infinity en
la división decimal, que pasa directamente a un gráfico.
NULLIF en una línea
NULLIF(a, b) devuelve NULL cuando a = b, y a en otro caso. Envuelve el denominador:
spend / NULLIF(conversions, 0)
Cuando conversions es 0, la división se convierte en spend / NULL, que es NULL: sin error, sin Infinity y
con un blanco en el gráfico, que es la respuesta honesta.
Los ceros reales de estos datos
Social es la fuente que peor convierte en Harbor & Pine. En mayo de 2025 la tienda gastó $10,170.19 en social y esas sesiones trajeron 0 conversiones de 204 sesiones de social. Septiembre y octubre de 2025 también tuvieron 0. Paid, con mucho más gasto, nunca llegó a cero en 2025, pero su mes más bajo (febrero) tuvo una sola conversión por $20,740.71. NULLIF maneja los ceros; un costo de $20,000 por conversión es una conversación de negocio, no un problema de datos.
NULLIF para valores centinela
El segundo uso de NULLIF es la limpieza. Los sistemas antiguos suelen guardar “desconocido” como un valor
centinela como 0, -1 o una cadena vacía. Convierte el centinela en un NULL real para que los
agregados lo ignoren:
SELECT AVG(NULLIF(quantity, 0)) AS avg_quantity
FROM order_items;
Ocho líneas de pedido tienen cantidad 0 (errores de captura). AVG(quantity) es 1.9954 y
AVG(NULLIF(quantity, 0)) es 1.9959. La diferencia es diminuta aquí, pero con un centinela como -1 en
miles de filas decide la respuesta. Para texto: NULLIF(TRIM(coupon_code), '').
Errores comunes
- Envolver toda la razón.
NULLIF(spend / conversions, 0)igual divide primero entre cero. - Inventar un valor.
COALESCE(conversions, 1)o una razón de 0 inventa un número. Si el gráfico tiene que mostrar algo, muestra NULL como “sin conversiones” en la etiqueta. - Filtrar las filas en cero. Elimina el error y también la evidencia de que se gastó dinero sin resultado.
En SQL Server
NULLIF es idéntico y es la protección estándar de T-SQL contra el error 8134 (división entre cero). Ojo
también con la división entera: conversions / sessions entre dos columnas INT devuelve 0, así que
multiplica antes por 1.0.
SELECT channel, spend / NULLIF(conversions, 0) AS cost_per_conversion FROM monthly_marketing; ¡Linterna encendida!
Practicaste: nullifdivision by zeroratiosdata cleaning
- Resuelto
- Sin pistas
- Al primer intento
