mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-14 07:42:28 +00:00
The function catalogue is now real rather than a pointer. Scalar functions are listed by taxonomy -- math, string, unicode, regex, date/time, array, map, struct, crypto, type -- and the names come from what datafusion-functions 54 actually registers, not from what DataFusion documents on main. Aggregate and window pages gain the same treatment. Two things the audit corrected rather than copied. SHOW TABLES does not work. DataFusion implements it over information_schema, which this session does not enable, so it fails at plan time. It was documented as working here, on the SHOW page and in three Manage tables; all four are fixed, and the SQL overview now lists the absence alongside SHOW COLUMNS. Prepared statements are a Flight SQL protocol feature, not a PREPARE statement. A script carrying PREPARE ... AS SELECT will not run, while the same intent expressed through a client will. The new page says so rather than copying DataFusion's syntax. Every section of the Documentation tab that has a SQL counterpart now links to it -- 27 of 76 non-SQL pages, each pointing at the specific statement rather than at the reference index.
136 lines
3.7 KiB
Plaintext
136 lines
3.7 KiB
Plaintext
---
|
|
title: "SELECT"
|
|
sidebarTitle: "Select"
|
|
description: "Projection, filtering, ordering, and composing queries out of other queries."
|
|
icon: table-columns
|
|
keywords: ["select", "where", "order by", "limit", "cte", "union", "distinct"]
|
|
---
|
|
|
|
<Badge color="red">Enterprise</Badge> [SQL runs on a deployment.](/sql)
|
|
|
|
```sql
|
|
[WITH cte AS (...)]
|
|
SELECT [ALL | DISTINCT] select_expr [, ...]
|
|
FROM from_item [[JOIN ...] ON ...]
|
|
[WHERE predicate]
|
|
[GROUP BY expr [, ...]] [HAVING predicate]
|
|
[WINDOW name AS (...)]
|
|
[ORDER BY expr [ASC | DESC] [NULLS FIRST | LAST] [, ...]]
|
|
[LIMIT n] [OFFSET n]
|
|
```
|
|
|
|
## Projection {#projection}
|
|
|
|
<CodeGroup>
|
|
```sql SQL
|
|
SELECT id, title, identifier FROM documents
|
|
```
|
|
|
|
```python Python icon="python"
|
|
tbl.search().select(["id", "title", "identifier"]).to_arrow()
|
|
```
|
|
|
|
```typescript TypeScript icon="square-js"
|
|
await tbl.query().select(["id", "title", "identifier"]).toArrow();
|
|
```
|
|
</CodeGroup>
|
|
|
|
Projection pushes into the scan in all three -- an unselected column is never
|
|
read off storage. On a table of images or video that is the difference between a
|
|
fast query and a slow one, so **prefer naming columns over `SELECT *`**.
|
|
|
|
Row metadata is available as [pseudo-columns](/sql/data-types#pseudo-columns)
|
|
(`_rowid`, `_rowaddr`, `_rowoffset`) but only when named, so they stay out of
|
|
`SELECT *`.
|
|
|
|
`DISTINCT` deduplicates the projected rows.
|
|
|
|
## Filtering {#filtering}
|
|
|
|
<CodeGroup>
|
|
```sql SQL
|
|
SELECT * FROM documents
|
|
WHERE identifier > 0 AND identifier < 1000000
|
|
```
|
|
|
|
```python Python icon="python"
|
|
tbl.search().where("identifier > 0 AND identifier < 1000000").to_arrow()
|
|
```
|
|
|
|
```typescript TypeScript icon="square-js"
|
|
await tbl.query().where("identifier > 0 AND identifier < 1000000").toArrow();
|
|
```
|
|
</CodeGroup>
|
|
|
|
The SDK `where` takes the same expression language, so a predicate moves between
|
|
them unchanged. A predicate on an indexed column becomes a `ScalarIndexQuery`
|
|
rather than a scan -- confirm with [`explain_plan`](/search/explain). See
|
|
[Filtering](/search/filtering) for the operators and their pushdown behaviour.
|
|
|
|
## Ordering and limiting {#order-limit}
|
|
|
|
```sql
|
|
SELECT id, title FROM documents
|
|
ORDER BY created_at DESC NULLS LAST
|
|
LIMIT 100 OFFSET 200
|
|
```
|
|
|
|
`ORDER BY` on a large table is a sort over the whole result, so pair it with a
|
|
`LIMIT` unless you genuinely need every row ordered.
|
|
|
|
## Set operations {#set-operations}
|
|
|
|
`UNION`, `UNION ALL`, `INTERSECT` and `EXCEPT` combine whole queries:
|
|
|
|
```sql
|
|
SELECT id FROM documents WHERE category = 'film'
|
|
UNION ALL
|
|
SELECT id FROM archived_documents WHERE category = 'film'
|
|
```
|
|
|
|
`UNION` deduplicates and `UNION ALL` does not, which makes `UNION ALL` the
|
|
cheaper one when you already know the inputs are disjoint.
|
|
|
|
## Common table expressions {#ctes}
|
|
|
|
```sql
|
|
WITH recent AS (
|
|
SELECT * FROM documents WHERE created_at > now() - INTERVAL '7 days'
|
|
)
|
|
SELECT category, count(*) FROM recent GROUP BY category
|
|
```
|
|
|
|
A CTE is scoped to the statement. One you want to keep is a
|
|
[view](/management/view); one whose rows you want stored is a
|
|
[materialized view](/management/materialized-view).
|
|
|
|
## Subqueries {#subqueries}
|
|
|
|
Subqueries are allowed anywhere an expression or a relation is -- in `FROM`, in
|
|
`WHERE` with `IN` or `EXISTS`, and as a scalar in the select list:
|
|
|
|
```sql
|
|
SELECT title
|
|
FROM documents
|
|
WHERE category_id IN (SELECT id FROM categories WHERE active)
|
|
```
|
|
|
|
## Namespaced tables {#namespaces}
|
|
|
|
A table inside a [namespace](/management/namespace) is written as a dotted path:
|
|
|
|
```sql
|
|
SELECT * FROM prod.events.clicks
|
|
```
|
|
|
|
## Reading the plan {#plans}
|
|
|
|
`EXPLAIN` and `EXPLAIN ANALYZE` work as DataFusion defines them, and produce the
|
|
same operators the SDK methods do:
|
|
|
|
```sql
|
|
EXPLAIN ANALYZE SELECT * FROM documents WHERE identifier < 1000
|
|
```
|
|
|
|
See [Explain](/search/explain) and [Explain Analyze](/search/explain-analyze).
|