mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-13 15:22:30 +00:00
Six groups were verbs -- Manage, Ingest, Train, Operate, Secure, Deploy -- and now name the thing rather than the action. Four more were sentence case. The page labels that were verb phrases follow: Add Computed Column becomes Computed Columns, Refresh Column becomes Column Refresh, Configuring Storage becomes Configuration, and Explain becomes Query Plans, which is also more accurate now that the page covers analyze as well. SQL statement pages take the keyword -- SELECT, DDL, DML, REFRESH, SHOW, EXPLAIN -- because a statement name is a noun and lowercase Select and Show read as instructions. Concept pages there keep noun phrases: Joins, Window Functions, Subqueries, Operators. Two duplicate labels are resolved on the way. Reranking sat in Semantic Search labelled Overview despite being the only page on its subject, and the Enterprise client page sat in SQL Reference labelled SQL next to the reference Overview; it is Client Connection now. Title case leaves prepositions and articles lowercase, so Needle in a Haystack and Hybrid Search on BEIR are already correct and unchanged.
72 lines
2.2 KiB
Plaintext
72 lines
2.2 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 on a deployment.](/sql)
|
|
|
|
Joining is the other thing the query builders cannot do. A question spanning two
|
|
tables is a SQL question.
|
|
|
|
## 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:
|
|
|
|
```sql
|
|
SELECT c.name, count(*) AS hits
|
|
FROM fts('my_docs', '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 join key with a [scalar index](/indexing/scalar-index) on it lets the planner
|
|
look rows up rather than scan for them. Check with
|
|
[`explain_plan`](/search/explain): an indexed key shows a `ScalarIndexQuery`,
|
|
an unindexed one shows a `LanceScan` feeding the join.
|
|
|
|
<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>
|