Search…
Joins
Join clauses range from simple to complex including joining complete subqueries on multiple conditions. qb has your back with all of these use cases.
Table of Contents
join
joinRaw
joinSub
joinWhere

join

Name
Type
Required
Default
Description
table
string | Expression | JoinClause
true
The name of the table or a Expression object from which the query is based. Alternatively, a configured JoinClause instance can be passed.
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
type
string
false
"inner"
The type of the join. Passing this as an argument is discouraged for readability. Use the dedicated methods like leftJoin and rightJoin where possible.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use the dedicated joinWhere or a join closure where possible.
Applies a join to the query. The simplest join is to a table based on two columns:
QueryBuilder
1
query.from( "users" )
2
.join( "posts", "users.id", "=", "posts.author_id" );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
Copied!
When doing a simple join using = as the operator, you can omit it and pass just the column names:
QueryBuilder
1
query.from( "users" )
2
.join( "posts", "users.id", "posts.author_id" );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
Copied!
``Expressions are also supported as the table argument (though you may prefer the readability of the joinRaw method):
QueryBuilder
1
query.from( "users" )
2
.join( query.raw( "posts (nolock)" ), "users.id", "=", "posts.author_id" );
Copied!
SQL Server
1
SELECT *
2
FROM [users]
3
JOIN posts (nolock)
4
ON [users].[id] = [posts].[author_id]
Copied!
Using raw will most likely tie your code to a specific database, so think carefully before using the raw method if you want your project to be database agnostic.
When you need to specify more clauses to join, you can pass a function as the second argument:
QueryBuilder
1
query.from( "users" )
2
.join( "posts", function( j ) {
3
j.on( "users.id", "=", "posts.author_id" );
4
j.on( "users.prefix", "=", "posts.prefix" );
5
} );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
5
AND `users`.`prefix` = `posts`.`prefix`
Copied!
You can specify where clauses in your joins as well.
QueryBuilder
1
query.from( "users" )
2
.join( "posts", function( j ) {
3
j.on( "users.id", "=", "posts.author_id" );
4
j.whereNotNull( "posts.published_date" );
5
} );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
5
AND `posts`.`published_date` IS NOT NULL
Copied!
Conditions inside a join clause can be grouped using a function.
QueryBuilder
1
query.from( "users" )
2
.join( "posts", function( j ) {
3
j.on( function( j1 ) {
4
j1.on( "users.id", "posts.author_id" )
5
.orOn( "users.id", "posts.reviewer_id" );
6
} );
7
j.whereNotNull( "posts.published_date" );
8
} );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON (
5
`users`.`id` = `posts`.`author_id`
6
OR `users`.`id` = `posts`.`reviewer_id`
7
)
8
AND `posts`.`published_date` IS NOT NULL
Copied!
A preconfigured JoinClause can also be passed to the join function. This allows you to extract shared pieces of code out to different functions.
QueryBuilder
1
var j = query.newJoin( "contacts" )
2
.on( "users.id", "posts.author_id" );
3
4
query.from( "users" ).join( j );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
Copied!

joinWhere

Name
Type
Required
Default
Description
table
string
true
The raw SQL string to use as the table.
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
type
string
false
"inner"
The type of the join. Passing this as an argument is discouraged for readability. Use the dedicated methods like leftJoin and rightJoin with a join function where possible.
Adds a join to another table based on a WHERE clause instead of an ON clause. WHERE clauses introduce parameters and parameter bindings whereas on clauses join between columns and don't need parameter bindings.
For simple joins, this specifies a column on which to join the two tables:
QueryBuilder
1
query.from( "users" )
2
.joinWhere( "contacts", "contacts.balance", "<", 100 );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `contacts`
4
WHERE `contacts`.`balance` < ?
Copied!
For complex joins, a function can be passed to first. This allows multiple on and where conditions to be applied to the join. See the documentation for join for more information.

joinRaw

Name
Type
Required
Default
Description
table
string
true
The raw SQL string to use as the table.
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
type
string
false
"inner"
The type of the join. Passing this as an argument is discouraged for readability. Use the dedicated methods like leftJoinRaw and rightJoinRaw where possible.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Uses the raw SQL provided to as the table for the join clause. All the other functionality of joinRaw matches the join method. Additionally, there are leftJoinRaw, rightJoinRaw, and crossJoinRaw methods available.
QueryBuilder
1
query.from( "users" )
2
.joinRaw( "posts (nolock)", "users.id", "posts.author_id" );
Copied!
SQL Server
1
SELECT *
2
FROM [users]
3
JOIN posts (nolock)
4
ON [users].[id] = [posts].[author_id]
Copied!
Using joinRaw will most likely tie your code to a specific database, so think carefully before using the joinRaw method if you want your project to be database agnostic.

joinSub

Name
Type
Required
Default
Description
alias
string
true
The alias for the derived table.
input
Function | QueryBuilder
true
Either a QueryBuilder instance or a function to define the derived query.
first
string | Expression | Function
true
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
type
string
false
"inner"
The type of the join. Passing this as an argument is discouraged for readability. Use the dedicated methods like leftJoinSub and rightJoinSub where possible.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Adds a join to a derived table. All the functionality of the join method applies to constrain the query. The derived table can be defined using a QueryBuilder instance:
QueryBuilder
1
var sub = query.newQuery()
2
.select( "id" )
3
.from( "contacts" )
4
.whereNotIn( "id", [ 1, 2, 3 ] );
5
6
query.from( "users as u" )
7
.joinSub( "c", sub, "u.id", "=", "c.id" );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
) AS `c`
8
ON `u`.`id` = `c`.`id`
Copied!
Alternatively, a function may be used to define the derived table:
QueryBuilder
1
query.from( "users as u" )
2
.joinSub( "c", function ( q ) {
3
q.select( "id" )
4
.from( "contacts" )
5
.whereNotIn( "id", [ 1, 2, 3 ] );
6
}, "u.id", "=", "c.id" );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
) AS `c`
8
ON `u`.`id` = `c`.`id`
Copied!
Complex join conditions are also possible by passing a function as the third parameter:
QueryBuilder
1
query.from( "users as u" )
2
.joinSub( "c", function ( q ) {
3
q.select( "id" )
4
.from( "contacts" )
5
.whereNotIn( "id", [ 1, 2, 3 ] );
6
}, function( j ) {
7
j.on( "u.id", "c.id" );
8
j.on( "u.type", "c.type" );
9
} );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
) AS `c`
8
ON `u`.`id` = `c`.`id`
9
AND `u`.`type` = `c`.`type`
Copied!

leftJoin

Name
Type
Required
Default
Description
table
string | Expression | JoinClause
true
The name of the table or a Expression object from which the query is based. Alternatively, a configured JoinClause instance can be passed.
(Note: a JoinClause instance may have a different join type than a left join. The JoinClause instance's join type will be used.)
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
QueryBuilder
1
query.from( "posts" )
2
.leftJoin( "users", "users.id", "posts.author_id" );
Copied!
MySQL
1
SELECT *
2
FROM `posts`
3
LEFT JOIN `users`
4
ON `users`.`id` = `posts`.`author_id`
Copied!

leftJoinRaw

Name
Type
Required
Default
Description
table
string
true
The raw SQL string to use as the table.
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Uses the raw SQL provided to as the table for the left join clause. All the other functionality of leftJoinRaw matches the join method.
QueryBuilder
1
query.from( "posts" )
2
.leftJoinRaw( "users (nolock)", "users.id", "posts.author_id" );
Copied!
SQL Server
1
SELECT *
2
FROM [posts]
3
LEFT JOIN users (nolock)
4
ON [users].[id] = [posts].[author_id]
Copied!
Using leftJoinRaw will most likely tie your code to a specific database, so think carefully before using the leftJoinRaw method if you want your project to be database agnostic.

leftJoinSub

Name
Type
Required
Default
Description
alias
string
true
The alias for the derived table.
input
Function | QueryBuilder
true
Either a QueryBuilder instance or a function to define the derived query.
first
string | Expression | Function
true
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Adds a left join to a derived table. All the functionality of the joinSub method applies to define and constrain the query.
QueryBuilder
1
var sub = query.newQuery()
2
.select( "id" )
3
.from( "contacts" )
4
.whereNotIn( "id", [ 1, 2, 3 ] );
5
6
query.from( "users as u" )
7
.leftJoinSub( "c", sub, "u.id", "=", "c.id" );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
LEFT JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
) AS `c`
8
ON `u`.`id` = `c`.`id`
Copied!

rightJoin

Name
Type
Required
Default
Description
table
string | Expression | JoinClause
true
The name of the table or a Expression object from which the query is based. Alternatively, a configured JoinClause instance can be passed.
(Note: a JoinClause instance may have a different join type than a right join. The JoinClause instance's join type will be used.)
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
QueryBuilder
1
query.from( "users" )
2
.rightJoin( "posts", "users.id", "posts.author_id" );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
RIGHT JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
Copied!

rightJoinRaw

Name
Type
Required
Default
Description
table
string
true
The raw SQL string to use as the table.
first
string | Expression | Function
false
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Uses the raw SQL provided to as the table for the right join clause. All the other functionality of rightJoinRaw matches the join method.
QueryBuilder
1
query.from( "users" )
2
.rightJoinRaw( "posts (nolock)", "users.id", "posts.author_id" );
Copied!
SQL Server
1
SELECT *
2
FROM [users]
3
LEFT JOIN posts (nolock)
4
ON [users].[id] = [posts].[author_id]
Copied!
Using rightJoinRaw will most likely tie your code to a specific database, so think carefully before using the rightJoinRaw method if you want your project to be database agnostic.

rightJoinSub

Name
Type
Required
Default
Description
alias
string
true
The alias for the derived table.
input
Function | QueryBuilder
true
Either a QueryBuilder instance or a function to define the derived query.
first
string | Expression | Function
true
The first column or Expression to join the table on. Alternatively, a function can be passed to configure complex join statements.
operator
string
false
"="
The boolean operator for the join clause.
second
string | Expression
false
The second column or Expression to join the table on.
where
boolean
false
false
Sets if the value of second should be interpreted as a column or a value. Passing this as an argument is discouraged. Use a closure to define the where clauses where possible.
Adds a right join to a derived table. All the functionality of the joinSub method applies to define and constrain the query.
QueryBuilder
1
var sub = query.newQuery()
2
.select( "id" )
3
.from( "contacts" )
4
.whereNotIn( "id", [ 1, 2, 3 ] );
5
6
query.from( "users as u" )
7
.rightJoinSub( "c", sub, "u.id", "=", "c.id" );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
RIGHT JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
) AS `c`
8
ON `u`.`id` = `c`.`id`
Copied!

crossJoin

Name
Type
Required
Default
Description
table
string | Expression | JoinClause
true
The name of the table or a Expression object from which the query is based. Alternatively, a configured JoinClause instance can be passed.
(Note: a JoinClause instance may have a different join type than a cross join. The JoinClause instance's join type will be used.)
QueryBuilder
1
query.from( "users" ).crossJoin( "posts" );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
CROSS JOIN `posts`
Copied!

crossJoinRaw

Name
Type
Required
Default
Description
table
string
true
The raw SQL string to use as the table.
Uses the raw SQL provided to as the table for the cross join clause. Cross joins cannot be further constrained with on or where clauses.
QueryBuilder
1
query.from( "users" ).crossJoinRaw( "posts (nolock)" );
Copied!
SQL Server
1
SELECT *
2
FROM [users]
3
CROSS JOIN posts (nolock)
Copied!
Using crossJoinRaw will most likely tie your code to a specific database, so think carefully before using the crossJoinRaw method if you want your project to be database agnostic.

crossJoinSub

Name
Type
Required
Default
Description
alias
string
true
The alias for the derived table.
input
Function | QueryBuilder
true
Either a QueryBuilder instance or a function to define the derived query.
Adds a cross join to a derived table. The derived table can be defined using a QueryBuilder instance or a function just as with joinSub. Cross joins cannot be constrained, however.
QueryBuilder
1
var sub = query.newQuery()
2
.select( "id" )
3
.from( "contacts" )
4
.whereNotIn( "id", [ 1, 2, 3 ] );
5
6
query.from( "users as u" ).crossJoinSub( "c", sub );
Copied!
MySQL
1
SELECT *
2
FROM `users` AS `u`
3
CROSS JOIN (
4
SELECT `id`
5
FROM `contacts`
6
WHERE `id` NOT IN (?, ?, ?)
7
)
Copied!

newJoin

Name
Type
Required
Default
Description
table
string | Expression
true
The name of the table or a Expression object from which the query is based.
type
string
false
"inner"
The type of the join. Valid types are inner, left, right, or cross.
Creates a new JoinClause. A JoinClause is a specialized version of a QueryBuilder. You may call on or orOn to constrain the JoinClause. You may also call any where methods.
Creating a JoinClause directly is useful when you need to share a join between different queries. You can create and configure the JoinClause in a function and pass it to queries as needed.
QueryBuilder
1
var j = query.newJoin( "contacts" )
2
.on( "users.id", "posts.author_id" );
3
4
query.from( "users" ).join( j );
Copied!
MySQL
1
SELECT *
2
FROM `users`
3
JOIN `posts`
4
ON `users`.`id` = `posts`.`author_id`
Copied!
Although a JoinClause can be passed to