La solicitud

De Rachel Adams, Líder de Atención al Cliente
Tu objetivo
Une returns con order_items y orders. Devuelve una fila por motivo con: reason, returns (número de devoluciones), avg_days (promedio de returned_on menos la fecha del pedido, en días, redondeado a 1) y max_days (la mayor de esas diferencias). Usa la fecha de calendario de order_date (convertida a DATE) para la diferencia.
- Lee de la tabla
orderspendiente - Lee de la tabla
order_itemspendiente - Muestra exactamente
reasonreturnsavg_daysmax_dayspendiente
Tu consulta
Cargando el editor…
Solución de referencia
| order_id | customer_id | order_date | status | channel |
|---|---|---|---|---|
| 1001 | 125 | 2023-01-01 20:51:19 | completed | web |
| 1002 | 156 | 2023-01-02 07:58:46 | completed | web |
| 1003 | 22 | 2023-01-02 10:25:27 | completed | marketplace |
| 1004 | 48 | 2023-01-02 11:21:51 | completed | marketplace |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Rachel, y por qué
Tablas
Datos de la tienda Harbor & Pine, listos para consultar.
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 |
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 |
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 |
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 |
La lección
El tiempo entre dos eventos es una métrica central para los analistas: días hasta el envío, días hasta la devolución, días desde el registro hasta la primera compra, tiempo para resolver un ticket. También es una de las partes menos portables de SQL.
Restar fechas
En DuckDB y Postgres, date - date devuelve un número entero de días:
SELECT DATE '2025-03-20' - DATE '2025-03-01'; -- 19
returned_on es un DATE pero order_date es un TIMESTAMP. Restar un timestamp da un
intervalo como 18 days 09:12:00, que no puedes promediar como un número simple con tanta facilidad. Convierte el
timestamp a fecha primero, para que ambos lados sean días de calendario:
r.returned_on - CAST(o.order_date AS DATE) AS days_to_return
Convertir responde a “cuántos días de calendario después”, que es como se escriben los plazos de devolución en una política. Si necesitaras horas (por ejemplo, el tiempo hasta la primera respuesta en un ticket de soporte), conservarías los timestamps y usarías una diferencia de epoch en su lugar.
Las formas con función
| base de datos | días entre start y end |
|---|---|
| DuckDB | end - start, o DATE_DIFF('day', start, end) |
| Postgres | end - start (fechas); EXTRACT(EPOCH FROM end - start) / 86400 para timestamps |
| MySQL | DATEDIFF(end, start) |
| BigQuery | DATE_DIFF(end, start, DAY) |
| Snowflake, SQL Server | DATEDIFF(day, start, end) |
Ojo con el orden de los argumentos: MySQL y BigQuery ponen el fin primero, DuckDB y Snowflake ponen el
inicio primero. Equivocarse invierte el signo, algo fácil de pasar por alto cuando solo miras
un promedio. Un MIN() rápido que sale negativo es la señal.
Sumar tiempo
Para ir en el otro sentido, suma un intervalo: order_date + INTERVAL 30 DAY funciona en DuckDB, MySQL y
BigQuery (como DATE_ADD en BigQuery), y Postgres escribe INTERVAL '30 days'. Así señalarías las
devoluciones que llegaron después de un plazo de 30 días:
WHERE r.returned_on > CAST(o.order_date AS DATE) + INTERVAL 30 DAY
El promedio y el máximo cuentan historias distintas
El promedio le dice a Rachel lo que es típico. El máximo le habla de la cola: si las devoluciones tardías
llegan con regularidad a 40 días, un plazo de 30 días convertiría algunas de las devoluciones aceptadas hoy en
rechazadas. En el trabajo también mirarías un percentil, por ejemplo
QUANTILE_CONT(days, 0.9) en DuckDB o PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY days) en
Postgres, y reportarías “el 90 % de las devoluciones llega en N días”. Esa frase es mucho más útil para una decisión
de política que un promedio.
Errores comunes
- Mezclar DATE y TIMESTAMP sin convertir, y luego promediar intervalos.
- Intercambiar el orden de los argumentos en funciones tipo
DATEDIFFentre dialectos. - Promediar sobre el grano equivocado. Aquí una fila es una devolución, que es lo que pidió Rachel.
En SQL Server
DATEDIFF(day, o.order_date, r.returned_on) cuenta las medianoches cruzadas, así que un pedido a las 23:59 y una devolución
a la mañana siguiente son 1 día. Suma tiempo con DATEADD(day, 30, order_date). Restar dos valores date con
- es un error allí.
¡Linterna encendida!
Practicaste: date arithmeticdate diffcastmulti join
- Resuelto
- Sin pistas
- Al primer intento
