La solicitud

De Nicole Bennett, Socia de Negocio de RR. HH.
Tu objetivo
Desde employees, devuelve employee_id, employee_name (first_name, un espacio, last_name), title y manager_name (el first_name del gerente, un espacio, last_name). Incluye a todos los empleados; manager_name es NULL para el empleado sin gerente.
- Lee de la tabla
employeespendiente - Muestra exactamente
employee_idemployee_nametitlemanager_namependiente - 60 filaspendiente
Tu consulta
Cargando el editor…
Solución de referencia
| employee_id | first_name | last_name | department | title |
|---|---|---|---|---|
| 1 | Catherine | Hale | Executive | Chief Executive Officer |
| 2 | Robert | Kim | Executive | Chief Operating Officer |
| 3 | Megan | Collins | Sales | Head of Sales |
| 4 | Chloe | Gutierrez | Sales | Account Executive |
Mote revisa tu resultado
Presiona Ejecutar. Cada fila que cumple el objetivo se vuelve una luciérnaga en tu linterna.
Lo que recibe Nicole, y por qué
Tablas
Datos de la tienda Harbor & Pine, listos para consultar.
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 |
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 |
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
Un self join une una tabla consigo misma. Es como trabajas con jerarquías guardadas en una sola tabla: empleados y gerentes, categorías y categorías padre, referidos entre clientes.
En employees, manager_id guarda el employee_id del gerente de cada persona. Para mostrar el nombre
del gerente, necesitas una segunda copia de la tabla que haga el papel de “gerente”:
SELECT
e.first_name AS employee,
m.first_name AS manager
FROM employees AS e
LEFT JOIN employees AS m ON m.employee_id = e.manager_id;
Aquí los alias no son opcionales. e y m son dos papeles de la misma tabla, y cada columna debe
indicar de qué papel viene.
Por qué LEFT JOIN
La CEO tiene manager_id NULL. Con un inner join, NULL = m.employee_id nunca coincide, y la CEO
desaparece del organigrama. LEFT JOIN la conserva, con las columnas del gerente en NULL. En cualquier jerarquía, la
cima del árbol no tiene padre, así que los self joins casi siempre son LEFT joins.
Concatenar texto
|| une cadenas en Postgres, DuckDB, SQLite, Oracle y Snowflake:
e.first_name || ' ' || e.last_name AS employee_name
MySQL usa CONCAT(first_name, ' ', last_name) (en MySQL, || significa OR salvo que se configure un modo SQL).
BigQuery admite tanto || como CONCAT. CONCAT también existe en Postgres y DuckDB, así que es la opción
más portable.
Difieren en los NULL: 'Hale' || NULL es NULL, mientras que CONCAT('Hale', NULL) devuelve 'Hale' en
Postgres y DuckDB (y NULL en MySQL). Para la CEO, m.first_name || ' ' || m.last_name es NULL,
que es lo que pidió Nicole. CONCAT devolvería un solo espacio, que parece vacío pero no es
NULL y rompería una comprobación posterior con IS NULL.
Subir más por el árbol
Un self join da un nivel. “El gerente del gerente” necesita un segundo join con un tercer alias:
LEFT JOIN employees AS m ON m.employee_id = e.manager_id
LEFT JOIN employees AS mm ON mm.employee_id = m.manager_id
Para una jerarquía de profundidad desconocida, Postgres, DuckDB, MySQL 8 y BigQuery admiten CTE recursivas
(WITH RECURSIVE), que recorren el árbol hasta que termina. Es un tema avanzado de entrevista y vale la pena
saber que existe.
Usos comunes para analistas
- Plantilla y salario por gerente (join y luego agrupar por el nombre del gerente).
- Encontrar empleados que ganan más que su gerente, una conocida pregunta de entrevista:
WHERE e.salary > m.salary. - Comparar filas dentro de una tabla, como pedidos del mismo cliente, aunque las funciones de ventana (capítulo 8) suelen hacerlo de forma más sencilla.
Errores comunes
- Usar un inner join. La CEO no tiene gerente, así que
JOIN employees AS mla descarta del organigrama. UsaLEFT JOIN. - Invertir la condición del join.
ON m.manager_id = e.employee_idempareja a cada persona con las personas que le reportan, no con su gerente. El gerente es la fila cuyo id es igual a tumanager_id:ON m.employee_id = e.manager_id. - Dejar columnas sin calificar. Ambas copias de la tabla tienen
first_name, así que unfirst_namea secas es ambiguo. Antepóne.om.a cada columna. - Usar
CONCATcuando el ticket quiere NULL. Para la CEO,CONCAT(m.first_name, ' ', m.last_name)devuelve un solo espacio, que parece vacío pero no pasa una comprobaciónIS NULL.
En SQL Server
Concatena con CONCAT(m.first_name, ' ', m.last_name) o con +. Difieren en NULL: para la CEO,
m.first_name + ' ' + m.last_name es NULL como ||, mientras que CONCAT trata NULL como texto vacío y devuelve
un solo espacio. || existe solo en las versiones más recientes (Azure SQL, SQL Server 2025).
¡Linterna encendida!
Practicaste: self joinleft joinconcatenation
- Resuelto
- Sin pistas
- Al primer intento
