Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Construcción de consultas con DataStore

DataStore proporciona métodos para construir consultas de estilo SQL que se traducen en consultas SQL optimizadas. Todas las operaciones se evalúan de forma diferida hasta que se necesitan los resultados.

Resumen de los métodos de consulta

Método Equivalente en SQL Descripción
select(*cols) SELECT cols Seleccionar columnas
filter(cond) WHERE cond Filtrar filas
where(cond) WHERE cond Alias de filter
sort(*cols) ORDER BY cols Ordenar filas
orderby(*cols) ORDER BY cols Alias de sort
limit(n) LIMIT n Limitar filas
offset(n) OFFSET n Saltar filas
distinct() DISTINCT Eliminar duplicados
groupby(*cols) GROUP BY cols Agrupar filas
having(cond) HAVING cond Filtrar grupos
join(right, ...) JOIN join DataStores
union(other) UNION Combinar resultados

Selección

select

Selecciona columnas específicas del DataStore.

select(*fields: Union[str, Expression]) -> DataStore

Ejemplos:

from chdb.datastore import DataStore
from pathlib import Path
Path("employees.csv").write_text("""\
name,age,city,salary,department,dept_id,status,email,manager_id,bonus
Alice,28,NYC,75000,Engineering,1,active,alice@company.com,3,5000
Bob,35,LA,85000,Engineering,1,active,bob@company.com,3,
Charlie,52,NYC,95000,Product,2,active,charlie@company.com,,10000
Diana,32,SF,70000,Design,3,active,diana@company.com,3,3000
Eve,23,LA,48000,Product,2,inactive,eve@company.com,2,
""")

ds = DataStore.from_file("employees.csv")

# Seleccionar por nombres de columna
result = ds.select('name', 'age', 'salary')

# Seleccionar todas las columnas
result = ds.select('*')

# Seleccionar con expresiones
result = ds.select(
    'name',
    (ds['salary'] * 12).as_('annual_salary'),
    ds['age'].as_('employee_age')
)

# Estilo equivalente en pandas
result = ds[['name', 'age', 'salary']]

Filtrado

filter / where

Filtra las filas según las condiciones. Ambos métodos son equivalentes.

filter(condition) -> DataStore
where(condition) -> DataStore  # alias

Ejemplos:

ds = DataStore.from_file("employees.csv")

# Condición única
result = ds.filter(ds['age'] > 30)
result = ds.where(ds['salary'] >= 50000)

# Múltiples condiciones (AND)
result = ds.filter((ds['age'] > 30) & (ds['department'] == 'Engineering'))

# Múltiples condiciones (OR)
result = ds.filter((ds['city'] == 'NYC') | (ds['city'] == 'LA'))

# Condición NOT
result = ds.filter(~(ds['status'] == 'inactive'))

# Condiciones de cadena de texto
result = ds.filter(ds['name'].str.contains('John'))
result = ds.filter(ds['email'].str.endswith('@company.com'))

# Comprobaciones de NULL
result = ds.filter(ds['manager_id'].notnull())
result = ds.filter(ds['bonus'].isnull())

# Condición IN
result = ds.filter(ds['department'].isin(['Engineering', 'Product', 'Design']))

# Condición BETWEEN
result = ds.filter(ds['salary'].between(50000, 100000))

# Filtros encadenados (AND)
result = (ds
    .filter(ds['age'] > 25)
    .filter(ds['salary'] > 50000)
    .filter(ds['city'] == 'NYC')
)

Filtrado estilo Pandas

# Indexación booleana (equivalente a filter)
result = ds[ds['age'] > 30]
result = ds[(ds['age'] > 30) & (ds['salary'] > 50000)]

# Método query
result = ds.query('age > 30 and salary > 50000')

Ordenación

sort / orderby

Ordena las filas por una o más columnas.

sort(*fields, ascending=True) -> DataStore
orderby(*fields, ascending=True) -> DataStore  # alias

Ejemplos:

ds = DataStore.from_file("employees.csv")

# Columna única ascendente
result = ds.sort('name')

# Columna única descendente
result = ds.sort('salary', ascending=False)

# Múltiples columnas
result = ds.sort('department', 'salary')

# Orden mixto (usar lista para el parámetro ascending)
result = ds.sort('department', 'salary', ascending=[True, False])

# Estilo Pandas
result = ds.sort_values('salary', ascending=False)
result = ds.sort_values(['department', 'salary'], ascending=[True, False])

Límites y paginación

limit

Limita el número de filas que se devuelven.

limit(n: int) -> DataStore

offset

Omite las primeras n filas.

offset(n: int) -> DataStore

Ejemplos:

ds = DataStore.from_file("employees.csv")

# Primeras 10 filas
result = ds.limit(10)

# Omitir las primeras 100, tomar las siguientes 50
result = ds.offset(100).limit(50)

# Estilo Pandas
result = ds.head(10)
result = ds.tail(10)
result = ds.iloc[100:150]

Distinct

distinct

Elimina las filas duplicadas.

distinct(subset=None, keep='first') -> DataStore

Ejemplos:

from pathlib import Path
Path("events.csv").write_text("""\
user_id,event_type,timestamp
1,click,2024-01-15 10:30:00
2,view,2024-01-15 11:00:00
1,purchase,2024-01-15 11:30:00
3,click,2024-01-16 09:00:00
2,click,2024-01-16 10:00:00
""")

ds = DataStore.from_file("events.csv")

# Eliminar todas las filas duplicadas
result = ds.distinct()

# Eliminar duplicados basándose en columnas específicas
result = ds.distinct(subset=['user_id', 'event_type'])

# Estilo Pandas
result = ds.drop_duplicates()
result = ds.drop_duplicates(subset=['user_id'])

Agrupación

groupby

Agrupa las filas por una o más columnas. Devuelve un objeto LazyGroupBy.

groupby(*fields, sort=True, as_index=True, dropna=True) -> LazyGroupBy

Ejemplos:

from pathlib import Path
Path("sales.csv").write_text("""\
region,product,category,amount,quantity,price,date,order_id
East,Widget,Electronics,5200,10,120,2024-01-15,1001
West,Gadget,Electronics,800,5,160,2024-02-20,1002
East,Gizmo,Home,6500,3,100,2024-03-10,1003
North,Widget,Electronics,4500,6,150,2024-06-18,1004
West,Gadget,Electronics,2000,8,250,2024-09-14,1005
""")

ds = DataStore.from_file("sales.csv")

# Agrupar por una sola columna
by_region = ds.groupby('region')

# Agrupar por múltiples columnas
by_region_product = ds.groupby('region', 'product')

# Agregación después de groupby
result = ds.groupby('region')['amount'].sum()
result = ds.groupby('region').agg({'amount': 'sum', 'quantity': 'mean'})

# Múltiples agregaciones
result = ds.groupby('category').agg({
    'price': ['min', 'max', 'mean'],
    'quantity': 'sum'
})

# Agregación con nombre
result = ds.groupby('region').agg(
    total_amount=('amount', 'sum'),
    avg_quantity=('quantity', 'mean'),
    order_count=('order_id', 'count')
)

having

Filtra los grupos después de la agregación.

having(condition: Union[Condition, str]) -> DataStore

Ejemplos:

# Filtrar grupos con total > 10000
result = (ds
    .groupby('region')
    .agg({'amount': 'sum'})
    .having(ds['sum'] > 10000)
)

# Usando having al estilo SQL
result = (ds
    .select('region', 'SUM(amount) as total')
    .groupby('region')
    .having('total > 10000')
)

JOIN

join

Realiza un join entre dos DataStores.

join(right, on=None, how='inner', left_on=None, right_on=None) -> DataStore

Parámetros:

Parámetro Tipo Predeterminado Descripción
right DataStore requerido DataStore de la derecha para hacer join
on str/list None Columnas usadas para el join
how str 'inner' Tipo de join: 'inner', 'left', 'right', 'outer'
left_on str/list None Columnas de join de la izquierda
right_on str/list None Columnas de join de la derecha

Ejemplos:

from pathlib import Path
Path("departments.csv").write_text("""\
dept_id,department_name
1,Engineering
2,Product
3,Design
""")

employees = DataStore.from_file("employees.csv")
departments = DataStore.from_file("departments.csv")

# Inner join en una sola columna
result = employees.join(departments, on='dept_id')

# Left join
result = employees.join(departments, on='dept_id', how='left')

# Join con nombres de columna distintos
result = employees.join(
    departments,
    left_on='department_id',
    right_on='id',
    how='inner'
)

# Merge al estilo Pandas
from chdb import datastore as pd
result = pd.merge(employees, departments, on='dept_id')
result = pd.merge(employees, departments, left_on='department_id', right_on='id')

union

Combina los resultados de dos DataStore.

union(other, all=False) -> DataStore

Ejemplos:

from pathlib import Path
Path("sales_2023.csv").write_text("""\
region,product,amount,date
East,Widget,1200,2023-06-15
West,Gadget,800,2023-09-20
North,Gizmo,600,2023-11-10
""")
Path("sales_2024.csv").write_text("""\
region,product,amount,date
East,Widget,1500,2024-03-10
North,Gizmo,900,2024-07-22
West,Gadget,1100,2024-05-05
""")

ds1 = DataStore.from_file("sales_2023.csv")
ds2 = DataStore.from_file("sales_2024.csv")

# UNION (elimina duplicados)
result = ds1.union(ds2)

# UNION ALL (conserva duplicados)
result = ds1.union(ds2, all=True)

# Estilo Pandas
from chdb import datastore as pd
result = pd.concat([ds1, ds2])

Expresiones condicionales

when

Crea expresiones CASE WHEN.

when(condition, value) -> CaseWhenBuilder

Ejemplos:

ds = DataStore.from_file("employees.csv")

# Caso simple case-when
result = ds.select(
    'name',
    ds.when(ds['salary'] > 100000, 'High')
      .when(ds['salary'] > 50000, 'Medium')
      .otherwise('Low')
      .as_('salary_tier')
)

# Con asignación de columna
ds['salary_tier'] = (
    ds.when(ds['salary'] > 100000, 'High')
      .when(ds['salary'] > 50000, 'Medium')
      .otherwise('Low')
)

Raw SQL

run_sql / sql

Ejecuta consultas en Raw SQL.

run_sql(query: str) -> DataStore
sql(query: str) -> DataStore  # alias

Ejemplos:

from chdb.datastore import DataStore

# Ejecutar Raw SQL
result = DataStore().sql("""
    SELECT 
        department,
        COUNT(*) as count,
        AVG(salary) as avg_salary
    FROM file('employees.csv', 'CSVWithNames')
    WHERE status = 'active'
    GROUP BY department
    HAVING count > 5
    ORDER BY avg_salary DESC
    LIMIT 10
""")

# SQL sobre un DataStore existente
ds = DataStore.from_file("employees.csv")
result = ds.sql("SELECT * FROM __table__ WHERE age > 30")

to_sql

Vea el SQL generado sin ejecutarlo.

to_sql(**kwargs) -> str

Ejemplos:

ds = DataStore.from_file("employees.csv")

query = (ds
    .filter(ds['age'] > 30)
    .groupby('department')
    .agg({'salary': 'mean'})
    .sort('mean', ascending=False)
)

print(query.to_sql())
# Salida:
# SELECT department, AVG(salary) AS mean
# FROM file('employees.csv', 'CSVWithNames')
# WHERE age > 30
# GROUP BY department
# ORDER BY mean DESC

Encadenamiento de métodos

Todos los métodos de consulta admiten el encadenamiento fluido:

from chdb.datastore import DataStore

ds = DataStore.from_file("sales.csv")

result = (ds
    .select('region', 'product', 'amount', 'date')
    .filter(ds['date'] >= '2024-01-01')
    .filter(ds['amount'] > 100)
    .groupby('region', 'product')
    .agg({
        'amount': ['sum', 'mean'],
        'date': 'count'
    })
    .having(ds['sum'] > 10000)
    .sort('sum', ascending=False)
    .limit(20)
)

# Ver SQL
print(result.to_sql())

# Ejecutar
df = result.to_df()

Alias

as_

Establece un alias para una columna o subconsulta.

as_(alias: str) -> DataStore

Ejemplos:

# Alias de columna
result = ds.select(
    ds['name'].as_('employee_name'),
    (ds['salary'] * 12).as_('annual_salary')
)

# Alias de subconsulta
subquery = ds.filter(ds['age'] > 30).as_('senior_employees')
Navigation