La solicitud

De Ryan Cooper, Gerente Regional de Ventas
Tu objetivo
Desde customers, devuelve state (sin espacios alrededor y convertido a mayúsculas) y customers (número de clientes), una fila por estado limpio.
- Lee de la tabla
customerspendiente - Muestra exactamente
statecustomerspendiente - 39 filaspendiente
Tu consulta
Cargando el editor…
Solución de referencia
| customer_id | first_name | last_name | city | |
|---|---|---|---|---|
| 1 | Owen | Hudson | owen.hudson@icloud.com | San Francisco |
| 2 | Douglas | Mendoza | dmendoza69@gmail.com | Atlanta |
| 3 | Henry | Brooks | hbrooks@lakesidecafe.com | Los Angeles |
| 4 | Brian | Graham | bgraham@bluecedarhomes.com | Seattle |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Ryan, y por qué
Tablas
Datos de la tienda Harbor & Pine, listos para consultar.
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 |
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
El texto escrito por personas o sincronizado entre sistemas es desordenado. En la tabla de clientes de Harbor & Pine, la
columna state contiene valores como 'CA', ' CA' y 'ca'. Para la base de datos son tres
cadenas distintas, así que GROUP BY state produce tres filas para California y todos los conteos quedan demasiado bajos.
Las funciones de limpieza
| función | hace | ejemplo |
|---|---|---|
TRIM(s) |
quita los espacios iniciales y finales | ' CA ' → 'CA' |
LTRIM(s), RTRIM(s) |
quita solo de un lado | |
UPPER(s) |
convierte a mayúsculas | 'ca' → 'CA' |
LOWER(s) |
convierte a minúsculas | 'Owen@ICloud.com' → 'owen@icloud.com' |
Existen con los mismos nombres en DuckDB, Postgres, MySQL y BigQuery. Anídalas para aplicar ambas:
SELECT UPPER(TRIM(state)) AS state, COUNT(*) AS customers
FROM customers
GROUP BY UPPER(TRIM(state));
Agrupa por la expresión limpia, no por la columna en bruto. Agrupar por state y seleccionar
UPPER(TRIM(state)) seguiría dando grupos separados que casualmente muestran la misma etiqueta, lo que
es aún más confuso.
Fíjate en que el alias reutiliza el nombre state. En GROUP BY, Postgres resuelve un state a secas como la
columna original, no como el alias, así que escribir la expresión completa (o GROUP BY 1) es la opción
sin ambigüedad.
Elige una forma canónica
Decide un estándar por columna y aplícalo de forma consistente: mayúsculas para los códigos de estado, minúsculas para
los correos y, para los nombres de ciudad, algo como INITCAP(TRIM(city)) en Postgres (DuckDB no tiene
INITCAP; comparar con LOWER(TRIM(city)) y mostrar cualquier ortografía es el truco habitual).
Encuentra primero el desorden
Antes de limpiar, mira:
SELECT state, COUNT(*)
FROM customers
GROUP BY state
ORDER BY state;
Ordenar pone las variantes una junto a otra. LENGTH(state) <> 2 encuentra valores con espacios sobrantes.
Los datos reales también pueden esconder espacios de no separación o tabuladores que TRIM no quita por defecto; el
TRIM(s, chars) de DuckDB y Postgres y REGEXP_REPLACE(s, '\s+', '', 'g') se ocupan de esos.
Limpia en la consulta, corrige en el origen
Limpiar dentro de las consultas funciona, pero todo analista tiene que acordarse de hacerlo. Si una columna es sistemáticamente desordenada, plantéaselo al equipo de ingeniería de datos para que se corrija una vez, aguas arriba, en el pipeline o en un modelo limpio. Menciona los conteos: “45 clientes tienen un estado con espacios sobrantes o minúsculas” es un ticket concreto sobre el que alguien puede actuar.
Errores comunes
- Limpiar solo en SELECT y no en GROUP BY ni en las condiciones de JOIN. Un join por
c.state = r.statedescarta en silencio las filas desordenadas; une por las expresiones limpias en su lugar. - Usar comparaciones
LIKEsin pasar a minúsculas, del capítulo 2. - Olvidar que
TRIM(NULL)es NULL. Limpiar no rellena valores que faltan; eso esCOALESCE, que usa el Desafío final.
En SQL Server
TRIM existe desde SQL Server 2017; el código más antiguo usa LTRIM(RTRIM(state)). LEN('NY ') es 2 porque LEN
ignora los espacios finales (usa DATALENGTH para verlos). Las intercalaciones por defecto no distinguen mayúsculas, así que
'ca' = 'CA' es verdadero y GROUP BY las fusiona, pero los espacios iniciales siguen dividiendo los grupos.
¡Linterna encendida!
Practicaste: trimupperlowerdata cleaninggroup by
- Resuelto
- Sin pistas
- Al primer intento
