La solicitud

De Thomas Whitaker, Director de Merchandising
Tu objetivo
Paso 1 de 2. Revisa el cambio. Para cada línea de pedido de los productos cuyo precio subió, etiqueta period ('before' si order_date < '2025-03-01', si no 'after') y price_paid ('old' si el unit_price de la línea es igual al precio más bajo del producto, si no 'new'). Devuelve period, price_paid y lines (el número de líneas de pedido), ordenado por period de forma descendente y luego por price_paid de forma descendente. Usa todas las líneas de pedido, sea cual sea el estado.
- Lee de la tabla
orderspendiente - Lee de la tabla
order_itemspendiente - Muestra exactamente
periodprice_paidlinespendiente
Paso 2 de 2. Compara en igualdad de condiciones. Usa pedidos completados, líneas con quantity > 0 y solo productos lanzados antes de 2024-01-01. Etiqueta cada línea con price_group 'raised' o 'unchanged'. Devuelve price_group, units_2024 y units_2025 (cantidad total del 1 de marzo al 31 de agosto de cada año), units_change_pct, revenue_2024 y revenue_2025 (ingreso neto, redondeado a 2) y revenue_change_pct. Ambas columnas de cambio son (2025 - 2024) * 100 / 2024 con sumas sin redondear, redondeadas a 1. Ordena por price_group.
- Lee de la tabla
productspendiente - Lee de la tabla
orderspendiente - Muestra exactamente
price_groupunits_2024units_2025units_change_pctrevenue_2024revenue_2025revenue_change_pctpendiente
Paso 1 · 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.
Paso 2 · tu consulta
Cargando el editor…
Solución de referencia
| product_id | name | category | subcategory | unit_price |
|---|---|---|---|---|
| 101 | Vale Velvet Loveseat | Furniture | Sofas | 1659.00 |
| 102 | Alder Oak Coffee Table | Furniture | Tables | 919.00 |
| 103 | Orchard Rattan Dining Chair | Furniture | Chairs | 789.00 |
| 104 | Upland Oak Bookcase | Furniture | Storage | 429.00 |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Thomas, 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 |
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 |
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 |
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 |
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
Qué estás revisando, y por qué
Antes de comparar nada, demuestra que estás mirando los productos correctos y la fecha correcta.
Thomas dice «unos 30 productos, 1 de marzo». Los datos pueden confirmar ambas cosas, porque
order_items guarda el precio pagado en cada línea, mientras que products.unit_price solo
guarda el precio de lista de hoy.
Un producto cuyo precio cambió tiene dos precios distintos entre sus líneas de pedido. Eso es una
condición sobre grupos, así que va en HAVING:
SELECT product_id, MIN(unit_price) AS old_price, MAX(unit_price) AS new_price
FROM order_items
GROUP BY product_id
HAVING MIN(unit_price) <> MAX(unit_price);
Esto devuelve 29 productos. La revisión del paso 1 etiqueta entonces cada una de sus líneas dos veces, por fecha y por precio, y cuenta las combinaciones. Si el cambio ocurrió limpiamente el 1 de marzo, solo existen dos combinaciones: antes con el precio viejo, después con el nuevo. Cualquier otra fila es un hallazgo en sí misma.
En igualdad de condiciones, con un grupo de control
El paso 2 responde la pregunta acordada. Tres decisiones hacen justa la comparación:
- Los mismos meses, con un año de diferencia. De marzo a agosto de 2025 frente a marzo a agosto de 2024. La temporada es la misma en ambos lados.
- Productos en igualdad de condiciones. Solo los productos lanzados antes del 1 de enero de 2024, para que todos estuvieran a la venta durante ambas ventanas completas.
- Un grupo de control. Todos los demás productos se etiquetan como
unchanged. Su crecimiento es la línea base: lo que la tienda hizo de todos modos.
El patrón para dos periodos lado a lado es la agregación condicional, el mismo que se usa en los informes año contra año:
SUM(CASE WHEN yr = 2024 THEN quantity END) AS u24,
SUM(CASE WHEN yr = 2025 THEN quantity END) AS u25
Guarda estas sumas en bruto en una CTE y calcula el porcentaje en el SELECT final, para que se
calcule con números sin redondear.
Cómo leer el resultado
| price_group | units_change_pct | revenue_change_pct |
|---|---|---|
| raised | 21.0 | 44.3 |
| unchanged | 9.2 | 13.4 |
Si la subida hubiera dañado la demanda, los productos con precio más alto crecerían menos que los que no cambiaron. Crecieron más. Los ingresos crecieron más rápido que las unidades en los productos con precio más alto porque cada unidad dejó cerca de 6% más y porque las ventas se desplazaron hacia los artículos más caros del grupo.
Errores comunes
BETWEEN '2025-03-01' AND '2025-08-31'sobre una marca de tiempo deja fuera la noche del 31 de agosto; usa un rango semiabierto.- Contar pedidos
cancelledorefundedsuma ventas que nunca ocurrieron. IN (SELECT ...)está bien para 29 ids; con millones de filas, un JOIN con la CTE es el hábito más rápido.
¡Linterna encendida!
Practicaste: data validationhavingcteconditional aggregationlike for likecontrol groupyoy
- Resuelto
- Sin pistas
- Al primer intento
