Joins y subconsultas
Los joins relacionan fuentes SQL y devuelven filas de una consulta. Las relaciones ORM describen asociaciones entre modelos y su carga; son APIs distintas.
Usa alias y nombres calificados para resolver columnas inequívocamente. Una subconsulta acepta un builder, SelectPlan o un callback síncrono que configura un builder nuevo. selectSub, whereExists, whereIn, joinSub y union reutilizan esta normalización. Los planes se incorporan por referencia; termina de configurarlos o clónalos antes de reutilizarlos.
from orionis.support.facades import DB
async def product_categories(): return await ( DB.table("products", alias="p") .leftJoin("categories", "p.category_id", "=", "c.id", alias="c") .select("p.id", "p.name") .selectRaw("c.name", alias="category_name") .orderBy("p.id") .get() )El ejemplo evita dos columnas name con la misma clave de resultado. Seleccionar columnas homónimas sin alias puede producir claves ambiguas al recuperar diccionarios. Para un modelo que luego guarde cambios o cargue relaciones conserva sus claves necesarias.
La disponibilidad de RIGHT/FULL JOIN depende del servidor. No se emula un JOIN no admitido ni se consulta otro motor automáticamente. Cada terminal mantiene una sola conexión: las subconsultas se compilan en el motor de la consulta exterior, aunque el builder incrustado haya elegido otra conexión.
Referencia por operación
Sección titulada «Referencia por operación»selectSub()
Sección titulada «selectSub()»selectSub(query: Any, alias: str) -> SelfAñade una subconsulta escalar con alias. El motor exige una columna y cardinalidad escalar; el builder no convierte varias filas en una lista.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products").select("id").selectSub(DB.table("products").selectRaw("MAX(price)").toPlan(), "highest_price")whereExists()
Sección titulada «whereExists()»whereExists(query: Any) -> SelfAñade EXISTS con AND. Úsalo para filtrar por la existencia de filas relacionadas sin hidratar modelos.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products", alias="p").whereExists(DB.table("categories", alias="c").select("c.id").whereColumn("c.id", "=", "p.category_id"))orWhereExists()
Sección titulada «orWhereExists()»orWhereExists(query: Any) -> SelfAñade EXISTS con OR. Úsalo para filtrar por la existencia de filas relacionadas sin hidratar modelos.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products", alias="p").orWhereExists(DB.table("categories", alias="c").select("c.id").whereColumn("c.id", "=", "p.category_id"))whereNotExists()
Sección titulada «whereNotExists()»whereNotExists(query: Any) -> SelfAñade NOT EXISTS con AND. Úsalo para filtrar por la existencia de filas relacionadas sin hidratar modelos.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products", alias="p").whereNotExists(DB.table("categories", alias="c").select("c.id").whereColumn("c.id", "=", "p.category_id"))orWhereNotExists()
Sección titulada «orWhereNotExists()»orWhereNotExists(query: Any) -> SelfAñade NOT EXISTS con OR. Úsalo para filtrar por la existencia de filas relacionadas sin hidratar modelos.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products", alias="p").orWhereNotExists(DB.table("categories", alias="c").select("c.id").whereColumn("c.id", "=", "p.category_id"))join(table: str | TableDefinition, first: Any=None, operator: str | None=None, second: str | None=None, *, alias: str | None=None) -> SelfAñade un JOIN INNER. Admite una condición de columnas o un callback JoinClause para combinar condiciones.
| Parámetro | Uso |
|---|---|
table | Nombre de tabla lógico o TableDefinition. Separa un esquema con un punto y usa alias explícitos en joins. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Una condición incompleta produce InvalidQueryException. Cada lado del ON debe ser una columna; el soporte del tipo de JOIN depende del motor.
from orionis.support.facades import DB
query = DB.table("products", alias="p").join("categories", "p.category_id", "=", "c.id", alias="c").select("p.id", "c.name")leftJoin()
Sección titulada «leftJoin()»leftJoin(table: str | TableDefinition, first: Any=None, operator: str | None=None, second: str | None=None, *, alias: str | None=None) -> SelfAñade un JOIN LEFT OUTER. Admite una condición de columnas o un callback JoinClause para combinar condiciones.
| Parámetro | Uso |
|---|---|
table | Nombre de tabla lógico o TableDefinition. Separa un esquema con un punto y usa alias explícitos en joins. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Una condición incompleta produce InvalidQueryException. Cada lado del ON debe ser una columna; el soporte del tipo de JOIN depende del motor.
from orionis.support.facades import DB
query = DB.table("products", alias="p").leftJoin("categories", "p.category_id", "=", "c.id", alias="c").select("p.id", "c.name")rightJoin()
Sección titulada «rightJoin()»rightJoin(table: str | TableDefinition, first: Any=None, operator: str | None=None, second: str | None=None, *, alias: str | None=None) -> SelfAñade un JOIN RIGHT OUTER. Admite una condición de columnas o un callback JoinClause para combinar condiciones.
| Parámetro | Uso |
|---|---|
table | Nombre de tabla lógico o TableDefinition. Separa un esquema con un punto y usa alias explícitos en joins. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Una condición incompleta produce InvalidQueryException. Cada lado del ON debe ser una columna; el soporte del tipo de JOIN depende del motor.
from orionis.support.facades import DB
query = DB.table("products", alias="p").rightJoin("categories", "p.category_id", "=", "c.id", alias="c").select("p.id", "c.name")fullJoin()
Sección titulada «fullJoin()»fullJoin(table: str | TableDefinition, first: Any=None, operator: str | None=None, second: str | None=None, *, alias: str | None=None) -> SelfAñade un JOIN FULL OUTER. Admite una condición de columnas o un callback JoinClause para combinar condiciones.
| Parámetro | Uso |
|---|---|
table | Nombre de tabla lógico o TableDefinition. Separa un esquema con un punto y usa alias explícitos en joins. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Una condición incompleta produce InvalidQueryException. Cada lado del ON debe ser una columna; el soporte del tipo de JOIN depende del motor.
from orionis.support.facades import DB
query = DB.table("products", alias="p").fullJoin("categories", "p.category_id", "=", "c.id", alias="c").select("p.id", "c.name")crossJoin()
Sección titulada «crossJoin()»crossJoin(table: str | TableDefinition, *, alias: str | None=None) -> SelfAñade un producto cartesiano sin condición ON. El número de combinaciones puede crecer como filas_izquierda * filas_derecha.
| Parámetro | Uso |
|---|---|
table | Nombre de tabla lógico o TableDefinition. Separa un esquema con un punto y usa alias explícitos en joins. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
from orionis.support.facades import DB
query = DB.table("products", alias="p").crossJoin("categories", alias="c").select("p.id", "c.id")joinSub()
Sección titulada «joinSub()»joinSub(query: Any, alias: str, first: Any=None, operator: str | None=None, second: str | None=None) -> SelfAñade una tabla derivada con JOIN INNER; alias es obligatorio y las columnas proyectadas deben ser direccionables.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Acepta un builder, un SelectPlan o un callback síncrono. No existe fullJoinSub en esta API.
from orionis.support.facades import DB
query = DB.table("products", alias="p").joinSub(DB.table("categories").select("id", "name"), "c", "p.category_id", "=", "c.id").select("p.id", "c.name")leftJoinSub()
Sección titulada «leftJoinSub()»leftJoinSub(query: Any, alias: str, first: Any=None, operator: str | None=None, second: str | None=None) -> SelfAñade una tabla derivada con JOIN LEFT OUTER; alias es obligatorio y las columnas proyectadas deben ser direccionables.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Acepta un builder, un SelectPlan o un callback síncrono. No existe fullJoinSub en esta API.
from orionis.support.facades import DB
query = DB.table("products", alias="p").leftJoinSub(DB.table("categories").select("id", "name"), "c", "p.category_id", "=", "c.id").select("p.id", "c.name")rightJoinSub()
Sección titulada «rightJoinSub()»rightJoinSub(query: Any, alias: str, first: Any=None, operator: str | None=None, second: str | None=None) -> SelfAñade una tabla derivada con JOIN RIGHT OUTER; alias es obligatorio y las columnas proyectadas deben ser direccionables.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
alias | Alias SQL de la proyección o tabla derivada; se utiliza para referenciar su resultado. |
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Acepta un builder, un SelectPlan o un callback síncrono. No existe fullJoinSub en esta API.
from orionis.support.facades import DB
query = DB.table("products", alias="p").rightJoinSub(DB.table("categories").select("id", "name"), "c", "p.category_id", "=", "c.id").select("p.id", "c.name")union()
Sección titulada «union()»union(query: Any) -> SelfCombina resultados mediante UNION eliminando duplicados.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Ambas consultas deben tener proyecciones compatibles en número y tipo; la validación final pertenece al motor.
from orionis.support.facades import DB
query = DB.table("products").select("name").union(DB.table("categories").select("name"))unionAll()
Sección titulada «unionAll()»unionAll(query: Any) -> SelfCombina resultados mediante UNION ALL conservando duplicados.
| Parámetro | Uso |
|---|---|
query | Builder, SelectPlan o callback síncrono que configura un builder nuevo. No se espera una coroutine. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Ambas consultas deben tener proyecciones compatibles en número y tipo; la validación final pertenece al motor.
from orionis.support.facades import DB
query = DB.table("products").select("name").unionAll(DB.table("categories").select("name"))on(first: str, operator: str, second: str) -> SelfAñade una comparación de columnas unida con AND.
| Parámetro | Uso |
|---|---|
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Los argumentos first/second son referencias de columna. Para un valor enlazado usa un filtro fuera del ON; JoinClause no ofrece where().
from orionis.orm.query.join_clause import JoinClause
query = JoinClause().on("p.category_id", "=", "c.id")orOn(first: str, operator: str, second: str) -> SelfAñade una comparación de columnas unida con OR.
| Parámetro | Uso |
|---|---|
first | Columna izquierda del ON, o callback síncrono que recibe JoinClause. |
operator | Operador de comparación. En condiciones básicas se valida contra SUPPORTED_OPERATORS. |
second | Referencia de columna derecha, no un valor de usuario. |
Resultado: el mismo builder mutable (Self); no ejecuta SQL.
Los argumentos first/second son referencias de columna. Para un valor enlazado usa un filtro fuera del ON; JoinClause no ofrece where().
from orionis.orm.query.join_clause import JoinClause
query = JoinClause().on("p.category_id", "=", "c.id").orOn("p.category_id", "=", "c.parent_id")conditions()
Sección titulada «conditions()»conditions() -> list[JoinCondition]Devuelve la lista viva de condiciones ON en orden. No ejecuta SQL ni la copia.
Resultado: list[JoinCondition].
Los argumentos first/second son referencias de columna. Para un valor enlazado usa un filtro fuera del ON; JoinClause no ofrece where().
from orionis.orm.query.join_clause import JoinClause
query = JoinClause().on("p.category_id", "=", "c.id").conditions()