La solicitud

De Jessica Turner, Gerente de Merchandising
Tu objetivo
Arregla la consulta. Sobre todas las líneas de pedido con quantity > 0, devuelve una fila por categoría de producto con: category, lines (número de líneas de pedido), returned_lines (líneas que tienen una fila en returns) y return_rate_pct (returned_lines / lines * 100, redondeado a 2).
- Lee de la tabla
productspendiente - Lee de la tabla
order_itemspendiente - Muestra exactamente
categorylinesreturned_linesreturn_rate_pctpendiente
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 |
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 |
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 |
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
Seis categorías, seis números enteros. Las tasas de devolución reales nunca son tan ordenadas. La consulta está bien en todas partes salvo por un carácter.
División entera en distintas bases de datos
Dividir dos enteros significa cosas distintas según dónde se ejecute la consulta:
- Postgres, SQL Server, Redshift, SQLite:
/entre dos enteros es división entera.402 / 5824es0. - DuckDB:
/siempre devuelve un decimal (402 / 5824es0.069...), y//es el operador de división entera. - MySQL, BigQuery, Snowflake:
/devuelve un decimal.
COUNT(*) es un entero en todas partes. Así que una consulta de Postgres escrita como
COUNT(r.return_id) * 100 / COUNT(*) producía porcentajes enteros allí, y una herramienta de migración
que conservó fielmente ese comportamiento en DuckDB escribió //. El fallo ya estaba en el informe
original.
Qué devuelve el starter
402 * 100 // 5824 es 6 para Textiles, y 103 * 100 // 1616 también es 6 para Furniture. Las tasas
reales son 6.90 y 6.37. Si la multiplicación hubiera ido después de la división, 402 // 5824 * 100,
todas las categorías mostrarían 0.
La solución
Haz decimal un operando antes de dividir:
ROUND(100.0 * COUNT(r.return_id) / COUNT(*), 2) AS return_rate_pct
100.0 es un literal decimal, así que toda la expresión se evalúa en decimales de izquierda a derecha.
Esta versión da la misma respuesta en todas las bases de datos de arriba, por eso los analistas la
escriben así incluso en DuckDB. CAST(COUNT(*) AS DOUBLE) también funciona, pero es más larga.
Redondear demasiado pronto
La otra forma de perder precisión es redondear antes de escalar: ROUND(402 / 5824, 2) * 100 convierte
0.069 en 0.07 y luego en 7, y Textiles se lee como 7% en lugar de 6.90%. Redondea una sola vez, al final,
a la precisión que muestra el informe.
Errores comunes
COUNT(r.return_id) / COUNT(*) * 1.0: en Postgres o SQL Server la división entera ya ocurrió; multiplicar después es tarde.COUNT(*)para las líneas devueltas: tras unLEFT JOINcuenta todas las líneas. Cuenta una columna dereturns.- Un inner join con
returns: descarta las líneas que nunca se devolvieron, así que todas las tasas pasan a ser 100%.
En SQL Server
Esta es la versión que más probablemente te muerda allí: / entre dos INT trunca.
SELECT 402 / 5824; -- 0
SELECT 100 * 402 / 5824; -- 6
SELECT 100.0 * 402 / 5824; -- 6.902472...
Escribe 100.0 * primero, exactamente como aquí.
En el trabajo
Las tasas de exactamente 0, 100 o números enteros son una señal de alarma en cualquier informe. Revisa la división antes de revisar los datos.
¡Linterna encendida!
Practicaste: debugginginteger divisionratesroundleft join
- Resuelto
- Sin pistas
- Al primer intento
