# Consultar con SQL
El Editor SQL ejecuta consultas en el motor de Nexus, que habla Spark SQL. Todos los ejemplos usan una pequeña tabla de muestra que usted crea primero, así puede seguirlos en un espacio de trabajo vacío.
## Antes de empezar [#antes-de-empezar]
- Cualquiera puede leer las tablas a las que tiene acceso.
- Crear una tabla requiere el derecho de cambiar la estructura; agregar filas, el de cambiar datos. Propietarios y administradores tienen ambos. Vea [Acceso a datos](/docs/es/data/data-access).
- Cuánto puede leer una consulta y cuántas filas devuelve dependen de su plan. Vea sus límites en , o con `nx.limits()` en código.
## Ejecutar una consulta [#ejecutar-una-consulta]
### Abra el Editor SQL [#abra-el-editor-sql]
Vaya a . El panel junto al editor lista sus **Tablas** por **Esquema**.
### Escriba una instrucción [#escriba-una-instrucción]
Escriba una instrucción, o haga clic en una tabla o columna para insertarla. El panel también ofrece **Vista previa de filas**, **Contar filas** y **Cambios**.
### Ejecútela [#ejecútela]
Seleccione **Ejecutar**, o presione ⌘ Enter (Ctrl Enter en Windows y Linux).
### Lea el resultado [#lea-el-resultado]
Las filas aparecen bajo el editor, con cuánto leyó la consulta (**Lee**, seguido de un tamaño). Seleccione **Página siguiente** para el resto de un resultado largo.
Antes de cada ejecución, el editor revisa cuánto leería la consulta. Si supera lo que permite su plan, nada se ejecuta y verá **Leería**, el tamaño, y cuánto está **permitido**. Acote la consulta y ejecútela de nuevo.
```python title="first_query.py"
from klarety import Nexus
with Nexus.connect() as nx:
result = nx.sql("SELECT current_date() AS today")
print(result.rows)
print(result.bytes_scanned)
```
`nx.sql()` espera mientras la instrucción se ejecuta; un reenvío tras una conexión caída nunca la ejecuta dos veces. Desde la línea de comandos: `klarety sql "SELECT current_date()"`.
## Crear una tabla de muestra [#crear-una-tabla-de-muestra]
El editor y la API ejecutan una instrucción a la vez. Ejecute cada bloque por separado.
Un nombre sin esquema, como `demo_orders`, va al esquema `default`.
```sql
CREATE TABLE demo_orders (
order_id BIGINT NOT NULL,
customer STRING,
country STRING,
status STRING,
amount DECIMAL(10, 2),
ordered_at TIMESTAMP
)
```
```sql
INSERT INTO demo_orders VALUES
(1, 'Ana', 'CO', 'paid', 120.50, TIMESTAMP '2026-10-01 09:15:00'),
(2, 'Bruno', 'BR', 'paid', 80.00, TIMESTAMP '2026-10-02 14:40:00'),
(3, 'Carla', 'CO', 'refunded', 45.25, TIMESTAMP '2026-10-03 11:05:00'),
(4, 'Diego', 'MX', 'paid', 210.00, TIMESTAMP '2026-10-03 16:30:00'),
(5, 'Ana', 'CO', 'paid', 60.00, TIMESTAMP '2026-10-05 08:00:00'),
(6, 'Elena', 'MX', 'paid', 99.90, TIMESTAMP '2026-10-06 19:20:00')
```
Las tablas de Nexus son tablas de Apache Iceberg, así que basta un `CREATE TABLE` simple. Omita `USING`, o escriba `USING iceberg`.
## Consultas de ejemplo [#consultas-de-ejemplo]
Ingresos y número de pedidos por país:
```sql
SELECT country,
COUNT(*) AS orders,
SUM(amount) AS revenue
FROM demo_orders
WHERE status = 'paid'
GROUP BY country
ORDER BY revenue DESC
```
Total acumulado de cada cliente, con una función de ventana:
```sql
SELECT customer,
ordered_at,
amount,
SUM(amount) OVER (PARTITION BY customer ORDER BY ordered_at) AS running_total
FROM demo_orders
ORDER BY customer, ordered_at
```
Pedidos por día:
```sql
SELECT date_trunc('DAY', ordered_at) AS day,
COUNT(*) AS orders
FROM demo_orders
GROUP BY 1
ORDER BY 1
```
Cambiar una fila:
```sql
UPDATE demo_orders SET status = 'refunded' WHERE order_id = 6
```
Al terminar, elimine la muestra en **Nexus Lakehouse** con **Más**, **Eliminar tabla**, o `nx.tables.delete("demo_orders")` en código. Se puede restaurar durante un tiempo (vea [Deshacer y restaurar](/docs/es/data/undo-and-restore)).
## Revisar cuánto lee una consulta antes de ejecutarla [#revisar-cuánto-lee-una-consulta-antes-de-ejecutarla]
Cada plan limita cuánto puede leer una consulta. Revisarlo antes no cuesta nada y no ejecuta nada.
El Editor SQL lo hace en cada ejecución.
```python title="estimate.py"
from klarety import Nexus
with Nexus.connect() as nx:
plan = nx.estimate("SELECT * FROM demo_orders")
print(plan["bytes_scanned"], plan["allowed_bytes"], plan["within_budget"])
```
Un rechazo de `estimate()` es el mismo que recibiría la ejecución, así que también comprueba con seguridad que una instrucción está permitida.
## Pasar valores como parámetros [#pasar-valores-como-parámetros]
Nunca pegue en el texto SQL un valor que escribió una persona. Nómbrelo `:name` y páselo en `params`. Cada valor se enlaza como un literal de texto, nunca se lee como SQL. Conviértalo con `CAST` cuando sea un número o una fecha:
```python title="parameters.py"
from klarety import Nexus
with Nexus.connect() as nx:
result = nx.sql(
"""
SELECT order_id, customer, amount
FROM demo_orders
WHERE country = :country
AND amount >= CAST(:minimum AS DECIMAL(10, 2))
ORDER BY amount DESC
""",
params={"country": "CO", "minimum": "50"},
)
for row in result.rows:
print(row)
```
Los nombres de parámetro empiezan con una letra o un guion bajo. Los parámetros están disponibles desde código, no en el Editor SQL.
Los parámetros son una función para desarrolladores que evita que los valores escritos cambien una consulta. Cambie a la vista de desarrolladores para ver cómo.
## Cuántas filas se devuelven [#cuántas-filas-se-devuelven]
Una consulta devuelve una página de filas a la vez. Los tamaños de página y de resultado dependen de su plan.
Si el resultado completo supera lo que permite su plan, verá **Solo se guarda la primera parte de este resultado**. Acote la consulta o agregue un `LIMIT`.
`max_rows` pide de 1 a 10.000 filas, y como máximo vuelve la página de su plan a la vez. Si hay más, `truncated` es verdadero y `nx.result_rows()` lee todas las filas, página por página:
```python title="all_rows.py"
from klarety import Nexus
with Nexus.connect() as nx:
result = nx.sql("SELECT * FROM demo_orders", max_rows=1000)
if result.truncated:
for row in nx.result_rows(result):
print(row)
else:
for row in result.rows:
print(row)
```
El resto de un resultado grande se guarda por un día. `result_truncated` es verdadero cuando incluso el resultado guardado superó el tamaño de su plan: acote la consulta.
Dos notas sobre valores: un número entero mayor que 2^53 vuelve como texto, conviértalo con `int()`; un `TIMESTAMP` vuelve en UTC sin el desfase escrito.
## Qué puede salir mal [#qué-puede-salir-mal]
Envíe una instrucción por ejecución. Una segunda instrucción después de un punto y coma se rechaza.
Filtre menos filas, seleccione menos columnas o agregue un `LIMIT`. En código esto lanza `OverBudgetError`.
Puede que no tenga acceso a una tabla que nombra, o que su acceso no permita el cambio. En código esto lanza `RefusedError`. Pregunte a un propietario o administrador; vea [Acceso a datos](/docs/es/data/data-access).
El motor arranca cuando se necesita, así que la primera consulta tras un rato sin uso tarda más. En código, `nx.warm()` lo arranca antes y responde de inmediato.
Su plan permite cierto número de consultas al mismo tiempo. En código, `StatementsBusyError` y `RateLimitedError` significan que nada se ejecutó: espere un momento y envíela de nuevo.
## Siguientes pasos [#siguientes-pasos]
- [Trabajar con tablas](/docs/es/data/tables): explore y edite filas sin SQL.
- [Agregar datos](/docs/es/data/add-data): cargue un archivo en una tabla.
- [SQL desde código](/docs/es/developers/sql): la referencia completa del SDK para consultas.