mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-20 18:52:28 +00:00
The existing docs have 254 findings from our shared Vale rules. Contributors would otherwise inherit these when editing the same lines. Clean up the prose across 80 pages: correct product names and a repeated word, simplify a few phrases, and replace dashes with punctuation that fits each sentence. The pinned Vale scan now reports zero findings, with no suppressions.
73 lines
2.3 KiB
Plaintext
73 lines
2.3 KiB
Plaintext
---
|
|
title: "Joins"
|
|
sidebarTitle: "Joins"
|
|
description: "Combining rows from more than one table, including across namespaces."
|
|
icon: link
|
|
keywords: ["join", "inner", "left", "outer", "cross", "namespace"]
|
|
---
|
|
|
|
<Badge color="red">Enterprise</Badge> [SQL runs in LanceDB Enterprise.](/sql)
|
|
|
|
Use SQL joins to combine rows from two or more tables.
|
|
|
|
## The join types {#types}
|
|
|
|
```sql
|
|
SELECT d.title, c.name
|
|
FROM documents AS d
|
|
JOIN categories AS c ON c.id = d.category_id
|
|
```
|
|
|
|
| | What it keeps |
|
|
| --- | --- |
|
|
| `[INNER] JOIN` | rows matching on both sides |
|
|
| `LEFT [OUTER] JOIN` | every left row, nulls where the right has no match |
|
|
| `RIGHT [OUTER] JOIN` | every right row |
|
|
| `FULL [OUTER] JOIN` | every row from both |
|
|
| `CROSS JOIN` | every combination (the product of the two) |
|
|
|
|
`USING (col)` is shorthand for an equality join on a shared column name, and
|
|
avoids repeating it in the select list.
|
|
|
|
## Across namespaces {#namespaces}
|
|
|
|
Tables in different [namespaces](/management/namespace) join by their dotted paths. The
|
|
catalog is one catalog, so there is nothing to federate:
|
|
|
|
```sql
|
|
SELECT c.id, u.email
|
|
FROM prod.events.clicks AS c
|
|
JOIN prod.reference.users AS u ON u.id = c.user_id
|
|
```
|
|
|
|
## Joining a search result {#search}
|
|
|
|
[`fts()`](/sql/functions#fts) is a table function, so its result is a relation
|
|
and joins like any other. This example assumes `my_docs` has `text` and
|
|
`category_id` columns, a full-text index on `text`, and a `categories` table
|
|
with `id` and `name` columns:
|
|
|
|
```sql
|
|
SELECT c.name, count(*) AS hits
|
|
FROM fts('my_docs', '{"match":{"column":"text","terms":"puppy"}}') AS m
|
|
JOIN categories AS c ON c.id = m.category_id
|
|
GROUP BY c.name
|
|
ORDER BY hits DESC
|
|
```
|
|
|
|
That composition is the reason full-text search is a relation rather than a
|
|
predicate: a `WHERE` clause has nowhere to put the relevance score.
|
|
|
|
## Performance {#performance}
|
|
|
|
A [scalar index](/indexing/scalar-index) can accelerate supported filters on
|
|
the input tables. An index on a join key does not by itself guarantee an
|
|
index lookup join. Use SQL [`EXPLAIN`](/sql/dql/explain) to inspect the scans,
|
|
filters, and join chosen for the complete statement.
|
|
|
|
<Warning>
|
|
Avoid selecting blob or vector columns you do not need on either side of a join.
|
|
The join multiplies rows before projection is applied in some plans, so a wide
|
|
column can be materialized many more times than the result has rows.
|
|
</Warning>
|