La solicitud

De Brian Mitchell, Analista de Finanzas
Tu objetivo
Desde products, devuelve product_id, name, unit_margin (unit_price menos unit_cost, redondeado a 2 decimales) y margin_pct (unit_margin dividido entre unit_price por 100, redondeado a 1 decimal). Incluye todos los productos; los productos sin costo mostrarán márgenes NULL, lo cual es lo esperado.
- Lee de la tabla
productspendiente - Muestra exactamente
product_idnameunit_marginmargin_pctpendiente - 120 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 Brian, 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 lista de SELECT no se limita a columnas que ya existen. Sirve cualquier expresión: aritmética, funciones
o constantes. Los analistas hacen esto constantemente para derivar métricas como el margen, el impuesto o el precio por unidad.
SELECT
name,
unit_price,
unit_price * 1.08 AS price_with_tax
FROM products;
Alias con AS
AS price_with_tax le da un nombre a la columna calculada, llamado alias. Sin él, la base de datos
inventa un encabezado como (unit_price * 1.08), que queda feo en una hoja de cálculo y es imposible de
referenciar limpiamente después. Usa alias en snake_case y minúsculas que describan la métrica. AS es
opcional en la mayoría de las bases de datos (unit_price * 1.08 price_with_tax también funciona), pero escribirlo hace que la
intención sea evidente y evita el error de la coma que falta del nivel anterior.
Redondeo
ROUND(x, 2) redondea a dos decimales. Redondea al final del todo, sobre el número final. Si redondeas un
valor intermedio y luego divides, el error se acumula:
-- good: compute from raw values, round once
ROUND((unit_price - unit_cost) / unit_price * 100, 1) AS margin_pct
NULL en la aritmética
Algunos productos no tienen unit_cost registrado. Cualquier operación aritmética con NULL devuelve NULL:
49.99 - NULL es NULL, no 49.99. Normalmente es lo que quieres aquí: un costo desconocido significa un
margen desconocido, y reportarlo como un margen del 100 % sería incorrecto. Aprenderás a reemplazar los NULL
de forma deliberada con COALESCE en el capítulo 6, pero hazlo solo cuando un valor por defecto tenga sentido de verdad.
División entera
En este conjunto de datos los precios son decimales, así que la división se comporta como esperas. Ten cuidado con las
columnas enteras. En Postgres, 7 / 2 devuelve 3 porque ambos lados son enteros. DuckDB y MySQL
devuelven 3.5, y BigQuery requiere DIV() para la división entera. Un hábito portable y seguro al
dividir conteos es multiplicar antes por 1.0, o convertir el tipo: CAST(a AS DECIMAL) / b.
Errores comunes
- Olvidar los paréntesis:
unit_price - unit_cost / unit_pricedivide primero y después resta. La multiplicación y la división tienen prioridad sobre la suma y la resta, igual que en la clase de matemáticas. - Referirse a un alias en la misma lista de SELECT:
SELECT unit_price - unit_cost AS m, m / unit_pricefalla en Postgres, MySQL y BigQuery. DuckDB lo permite, pero conviene repetir la expresión o usar una subconsulta para que tu SQL funcione en todas partes.
En SQL Server
La aritmética, AS y ROUND funcionan igual. Dos diferencias te pueden pillar: un entero dividido entre un entero
se trunca (7 / 2 es 3), y el texto se une con + o CONCAT en lugar de ||:
SELECT Name + ' (' + Color + ')' AS Label,
ROUND((ListPrice - StandardCost) / ListPrice * 100, 1) AS MarginPct
FROM Production.Product; ¡Linterna encendida!
Practicaste: expressionsaliasroundnull arithmetic
- Resuelto
- Sin pistas
- Al primer intento
