> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ondb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL Interface

> Query and insert data using SQL syntax

OnDB supports SQL syntax as an alternative to the query builder. Use `client.sql()` for SELECT queries and `client.sqlInsert()` for INSERT statements. Tables are addressed using the `app_id::collection` format.

## SQL Queries

Execute SELECT queries against your collections using `client.sql()`.

```typescript theme={null}
const result = await client.sql(
  'SELECT * FROM my_app::users WHERE email = "alice@example.com"',
  { includeHistory: false }
);

console.log(result.data);       // Array of matching records
console.log(result.count);      // Total count
console.log(result.query);      // Executed query string
console.log(result.app_id);     // App ID
console.log(result.collection); // Collection name
```

### Include History

By default, queries return only the latest version of each record. Set `includeHistory` to `true` to retrieve all historical versions.

```typescript theme={null}
const result = await client.sql(
  'SELECT * FROM my_app::users WHERE active = true',
  { includeHistory: true }
);
```

## SQL Inserts

Use `client.sqlInsert()` to insert data with SQL INSERT statements.

```typescript theme={null}
await client.sqlInsert(
  'INSERT INTO my_app::users (email, name, active) VALUES ("alice@example.com", "Alice", true)'
);
```

## SQL Syntax Reference

OnDB supports a subset of SQL syntax. Tables must be referenced in `app_id::collection` format.

| Statement         | Syntax                                                             |
| ----------------- | ------------------------------------------------------------------ |
| **SELECT**        | `SELECT * FROM app::collection WHERE ...`                          |
| **SELECT fields** | `SELECT email, name FROM app::collection`                          |
| **INSERT**        | `INSERT INTO app::collection (field1, field2) VALUES (val1, val2)` |
| **WHERE**         | `WHERE field = value AND field2 > value2`                          |
| **ORDER BY**      | `ORDER BY field ASC` or `ORDER BY field DESC`                      |
| **LIMIT**         | `LIMIT 10`                                                         |
| **OFFSET**        | `OFFSET 20`                                                        |
| **GROUP BY**      | `GROUP BY field`                                                   |

### Examples

```sql theme={null}
-- Select with filtering and sorting
SELECT * FROM my_app::products WHERE price > 10 ORDER BY price ASC LIMIT 20

-- Select specific fields
SELECT name, email, created_at FROM my_app::users WHERE active = true

-- Pagination
SELECT * FROM my_app::logs ORDER BY timestamp DESC LIMIT 50 OFFSET 100

-- Insert a record
INSERT INTO my_app::users (email, name, active) VALUES ("bob@example.com", "Bob", true)
```

## Response Format

The `sql()` method returns a `SqlQueryResponse`:

```typescript theme={null}
interface SqlQueryResponse {
  data: any[];       // Array of matching records
  count: number;     // Number of records returned
  query: string;     // The SQL query that was executed
  app_id: string;    // Application ID
  collection: string; // Collection name
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Query Builder" icon="magnifying-glass" href="/querying/query-builder">
    Fluent query API with type-safe conditions
  </Card>

  <Card title="Predefined Queries" icon="bookmark" href="/querying/predefined-queries">
    Named, parameterized queries with public endpoints
  </Card>
</CardGroup>
