Nivel 1 · Productos con precio superior al promedio
¿Es nuevo para ti? Lee primero el concepto: Una consulta es una tabla que puedes reutilizar
0 de 3
La solicitud

De Jessica Turner, Gerente de Merchandising
Tu objetivo
Desde products, devuelve product_id, name, unit_price y avg_price (el unit_price promedio de todos los productos, redondeado a 2) de todo producto cuyo unit_price sea mayor que ese promedio (compara con el promedio sin redondear).
- Lee de la tabla
productspendiente - Muestra exactamente
product_idnameunit_priceavg_pricependiente - 33 filaspendiente
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 Jessica, y por qué
Tablas
Datos de la tienda Harbor & Pine, listos para consultar.
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 |
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 |
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
La consulta del código inicial falla: AVG no puede aparecer en WHERE, porque WHERE trabaja una fila a la vez
(el quiz del capítulo 4). Necesitas el promedio como un solo número primero y luego comparar cada fila con él. Una
subconsulta hace justo eso:
SELECT product_id, name, unit_price
FROM products
WHERE unit_price > (SELECT AVG(unit_price) FROM products);
La consulta interna se ejecuta por sí sola y devuelve un valor. La consulta externa lo usa entonces como una constante.
Subconsultas escalares
Una subconsulta que devuelve exactamente una fila y una columna es una subconsulta escalar. Puede ir en cualquier lugar donde vaya un solo valor: WHERE, SELECT, incluso dentro de aritmética:
SELECT
name,
unit_price,
ROUND(unit_price - (SELECT AVG(unit_price) FROM products), 2) AS above_avg_by
FROM products;
Si la subconsulta devuelve más de una fila, la consulta da error (“more than one row returned by a subquery”). Si no devuelve filas, el valor es NULL, lo que hace que toda comparación sea desconocida y no devuelva nada. Ambas son buenas razones para ejecutar primero la subconsulta sola.
Tres lugares donde puede vivir una subconsulta
| ubicación | devuelve | uso de ejemplo |
|---|---|---|
WHERE x > (SELECT ...) |
un valor | por encima del promedio |
WHERE x IN (SELECT ...) |
una lista | clientes que pidieron en 2025 |
FROM (SELECT ...) AS t |
una tabla | agregar y luego volver a agregar |
La última, una tabla derivada, es lo que usaste en el capítulo 5 para preagregar antes de un join.
Postgres y MySQL exigen un alias para ella (AS t); DuckDB y BigQuery no, pero añade siempre uno.
Subconsultas correlacionadas
Una subconsulta puede referirse a la fila externa. Esta compara cada producto con el promedio de su propia categoría:
SELECT p.name, p.category, p.unit_price
FROM products AS p
WHERE p.unit_price > (
SELECT AVG(p2.unit_price)
FROM products AS p2
WHERE p2.category = p.category
);
Lógicamente la consulta interna se ejecuta una vez por cada fila externa. Los optimizadores modernos (el de DuckDB en especial) la reescriben
como un join, pero en algunas bases de datos las subconsultas correlacionadas sobre tablas grandes son lentas. El capítulo 8 muestra la
versión con función de ventana, AVG(unit_price) OVER (PARTITION BY category), que suele ser más clara.
¿Promedio de qué?
El “precio promedio” aquí es el promedio sobre los productos: cada producto cuenta una vez. El precio promedio pagado en las líneas de pedido ponderaría más a los más vendidos y daría un número distinto. Cuando un ticket dice “promedio”, decide sobre qué población es y dilo.
Errores comunes
- Comparar con un promedio redondeado. Redondea solo lo que muestras; compara con el valor exacto.
- Usar
=con una subconsulta que puede devolver varias filas. UsaINen su lugar.
En SQL Server
Las subconsultas escalares y correlacionadas se escriben igual. Una subconsulta escalar que devuelve dos filas falla con
“Subquery returned more than 1 value”. AVG de una columna entera devuelve un entero allí, así que escribe
AVG(CAST(x AS decimal(10, 2))) al promediar conteos o montos en dólares enteros.
¡Linterna encendida!
Practicaste: subqueryscalar subqueryavg
- Resuelto
- Sin pistas
- Al primer intento
