All pages
Powered by GitBook
1 of 14

Building Queries

Selects

Specifying A Select Clause

You may not always want to select all columns from a database table. You can influence the select list of a query with the following methods.

Individual columns can contain fully-qualified names (some_table.some_column), table aliases (alias.some_column), and even set column aliases themselves (some_column AS c). The columns argument can be a single column, a list of columns (comma-separated), or an array of columns.

select

Name

Type

Required

Default

Description

columns

string | array

false

​"*"

A single column, list of columns, or array of columns to retrieve.

When calling select any previous columns are discarded. If you want to incrementally select columns, use the addSelect method.

If you pass no columns to this method, it will default to "*".

QueryBuilder
query.select( [ "fname AS firstName", "age" ] ).from( "users" );
SQL (MySQL)
SELECT `fname` AS `firstName`, `age` FROM `users`

distinct

Name

Type

Required

Default

Description

state

boolean

false

​true

Value to set the distinct flag.

Calling distinct will cause the query to be executed with the DISTINCT keyword.

QueryBuilder
query.select( "username" ).distinct().from( "users" );
SQL (MySQL)
SELECT DISTINCT `username` FROM `users`

distinct applies to the entire query, not just certain fields.

addSelect

Name

Type

Required

Default

Description

columns

string | array

true

​

A single column, list of columns, or array of columns to add to the select.

This method adds the columns passed to it to the currently selected columns.

If the QueryBuilder is currently selecting all columns ("*") when this method is called, the incoming columns will becoming the only columns selected.

QueryBuilder
query.addSelect( [ "fname AS firstName", "age" ] ).from( "users" );
SQL (MySQL)
SELECT `fname` AS `firstName`, `age` FROM `users`

selectRaw

Name

Type

Required

Default

Description

expression

any

true

​

The raw expression for the select statement.

bindings

array

false

[]

Any bindings needed for the raw expression.

A shortcut to use a raw expression in the select clause.

The expression is added to the other already selected columns.

(To learn more about raw and expressions, check out the docs on Raw Expressions.)

QueryBuilder
query.selectRaw( "YEAR(birthdate) AS birth_year" ).from( "users" );
SQL (MySQL)
SELECT YEAR(birthdate) AS birth_year FROM `users`

subSelect

Name

Type

Required

Default

Description

alias

string

true

​

The alias for the subselect expression.

query

Function | QueryBuilder

true

The callback or query to use in the subselect.

The method lets you pass either a callback or a QueryBuilder instance to be used as a subselect expression. If a callback is passed it will be passed a new query instance as the only parameter.

The subselect is added to the other already selected columns.

QueryBuilder
query.subSelect( "last_login_date", function( q ) {
    q.selectRaw( "MAX(created_date)" )
        .from( "logins" )
        .whereColumn( "users.id", "logins.user_id" );
} ) ).from( "users" );
SQL (MySQL)
SELECT (
    SELECT MAX(created_date)
    FROM `logins`
    WHERE `users`.`id` = `logins`.`user_id`
) AS `last_login_date`
FROM `users

clearSelect

Name

Type

Required

Default

Description

No arguments

``

Clears out the selected columns for a query along with any configured select bindings.

QueryBuilder
query.from( "users" )
    .select( [ "fname AS firstName", "age" ] )
    .clearSelect();
SQL (MySQL)
SELECT * FROM `users`

reselect

Name

Type

Required

Default

Description

columns

string | array

false

​"*"

A single column, list of columns, or array of columns to retrieve.

Clears out the selected columns for a query along with any configured select bindings. Then sets a selection of columns to select from the query. Any valid argument to select can be passed here.

QueryBuilder
query.from( "users" )
    .select( [ "fname AS firstName", "age" ] )
    .reselect( "username" );
SQL (MySQL)
SELECT `username` FROM `users`

reselectRaw

Name

Type

Required

Default

Description

expression

any

true

​

The raw expression for the select statement.

bindings

array

false

[]

Any bindings needed for the raw expression.

Clears out the selected columns for a query along with any configured select bindings. Then adds an Expression or array of expressions to the already selected columns.

QueryBuilder
query.from( "users" )
    .select( [ "fname AS firstName", "age" ] )
    .reselectRaw( "YEAR(birthdate) AS birth_year" );
SQL (MySQL)
SELECT YEAR(birthdate) AS birth_year FROM `users`

From

from

Name

Type

Required

Default

Description

from

string | Expression

true

​

The name of the table or a Expression object from which the query is based.

Used to set the base table for the query.

QueryBuilder
query.from( "users" );
MySQL
SELECT * FROM `users`

You can optionally specify an alias for the table.

QueryBuilder
query.from( "users as u" );
MySQL
SELECT * FROM `users` AS `u`

table

Name

Type

Required

Default

Description

table

string | Expression

true

​

The name of the table or a Expression object from which the query is based.

An alias for from where you like how calling table looks.

QueryBuilder
query.table( "users" ).insert( { "name" = "jon" } );
MySQL
INSERT INTO `users` (`name`) VALUES (?)

fromRaw

Name

Type

Required

Default

Description

from

string

true

​

The sql snippet to use as the table.

bindings

array

false

[]

Any bindings needed for the expression.

Sometimes you need more control over your from clause in order to add grammar specific instructions, such as adding SQL Server table hints to your queries.

QueryBuilder
query.fromRaw( "[users] u (nolock)" ).get();
SQL Server
SELECT * FROM [users] u (nolock) 

Since the fromRaw() takes your string verbatim, it's important that you make sure your SQL declaration is escaped properly. Failure to properly escape your table names may result in SQL errors.

Using fromRaw will most likely tie your code to a specific database, so think carefully before using the fromRaw method if you want your project to be database agnostic.

Many database engines allow you to define User Defined Functions. For example, SQL Server allows you to define UDFs that will return a table. In these type of cases, it may be necessary to bind parameters to your from clause.

You can bind parameters to the fromRaw() method by passing a secondary argument that is an array of the parameters to bind.

QueryBuilder
query.fromRaw(
    "dbo.generateDateTable(?, ?, ?) as dt",
    [ "2017-01-01", "2017-12-31", "m" ]
).get();
SQL Server
SELECT * FROM dbo.generateDateTable(?, ?, ?) as dt

fromSub

Name

Type

Required

Default

Description

alias

string

true

​

The alias for the derived table.

input

Function | QueryBuilder

true

Either a QueryBuilder instance or a closure to define the derived query.

Complex queries often contain derived tables. Derived tables are essentially a temporal table defined as a subquery in the from statement.

QueryBuilder
query.select( [ "firstName", "lastName" ] )
    .fromSub( "legalUsers", function ( q ) {
        q.select( [ "lName as lastName", "fName as firstName" ] )
            .from( "users" )
            .where( "age", ">=", 21 )
        ;
    } )
    .orderBy( "lastName" )
    .get()
MySQL
SELECT `firstName`, `lastName`
FROM (
    SELECT `lName` as `lastName`, `fName` as `firstName`
    FROM `users`
    WHERE `age` >= 21
) AS `legalUsers`
ORDER BY `lastName`

In additional a function callback, a separate QueryBuilder instance can be passed to the fromSub method.

QueryBuilder
var legalUsersQuery = query
    .select( [ "lName as lastName", "fName as firstName" ] )
    .from( "users" )
    .where( "age", ">=", 21 );

query.select( [ "firstName", "lastName" ] )
    .fromSub( "legalUsers", legalUsersQuery )
    .orderBy( "lastName" )
    .get();
MySQL
SELECT `firstName`, `lastName`
FROM (
    SELECT `lName` as `lastName`, `fName` as `firstName`
    FROM `users`
    WHERE `age` >= 21
) AS `legalUsers`
ORDER BY `lastName`

withAlias

Name
Type
Required
Default Value
Description

alias

string

The new alias to use for the table.

Adds an alias to the specified from table or renames a current alias. Any existing aliased values in columns, wheres, joins, groupBys, or orders that match the previous alias will be remapped to the new alias. This includes the full table name when used as an alias.

qb.from( "users" ).select( [ "users.name", "birthdate" ] );
// SELECT "users"."name", "birthdate" FROM "users"
qb.withAlias( "u1" );
// SELECT "u1"."name", "birthdate" FROM "users" AS "u1"

Loading...

Loading...

Order By

The orderBy method seems simple but has a lot of depth depending on the type of arguments you pass in.

Calling orderBy multiple times appends to the order list.

Order By (String)

Name

Type

Required

Default

Description

column

any

true

direction

string

false

"asc"

The direction by which to order the query. Accepts "asc"or "desc".

QueryBuilder
query.from( "users" )
    .orderBy( "email" );
MySQL
SELECT *
FROM `users`
ORDER BY `email` ASC

Calling orderBy multiple times will append to the order list.

QueryBuilder
query.from( "users" )
    .orderBy( "email" )
    .orderBy( "username", "desc" );
MySQL
SELECT *
FROM `users`
ORDER BY
  `email` ASC,
  `username` DESC
QueryBuilder
query.from( "users" )
    .orderBy( query.raw( "DATE(created_at)" ) );
MySQL
SELECT *
FROM `users`
ORDER BY DATE(created_at)

Order By (List)

Name

Type

Required

Default

Description

column

any

true

The list of the columns to order by. Each column can optionally declare it's sort direction after a pipe delimiter. (e.g. `"height

desc"`).

direction

string

false

"asc"

The direction by which to order the query. Accepts "asc"or "desc". This value will be used as the default value for all entries in the column list that fail to specify a direction for a specific column.

QueryBuilder
query.from( "users" )
    .orderBy( "email|asc,username", "desc" );
MySQL
SELECT *
FROM `users`
ORDER BY
  `email` ASC,
  `username` DESC

Order By (Array of Strings)

Order By (Array of Structs)

Order By (Subquery)

You can order with a subquery using either a function or a QueryBuilder instance.

Order By Raw

clearOrders

reorder

Group By and Having

groupBy

Name

Type

Required

Default

Description

groups

string | array

true

A single column name, a list of column names, or an array of column names to group by. An Expression can be passed as well.

Passing a single string will group by that one column.

QueryBuilder
query.from( "users" )
    .groupBy( "country" );
MySQL
SELECT *
FROM `users`
GROUP BY `country`

You can also pass a list of column names. A single comma (",") will be used as the delimiter.

QueryBuilder
query.from( "users" )
    .groupBy( "country,city" );
MySQL
SELECT *
FROM `users`
GROUP BY `country`, `city`

An array of column names can be provided.

QueryBuilder
query.from( "users" )
    .groupBy( [ "country", "city" ] );
MySQL
SELECT *
FROM `users`
GROUP BY `country`, `city`

Calling groupBy multiple times will to the current groups.

QueryBuilder
query.from( "users" )
    .groupBy( "country" )
    .groupBy( "city" );
MySQL
SELECT *
FROM `users`
GROUP BY `country`, `city`

An Expression can be passed in place of a column.

QueryBuilder
query.from( "users" )
    .groupBy( query.raw( "DATE(created_at)" ) );
MySQL
SELECT *
FROM `users`
GROUP BY DATE(created_at)

having

Name

Type

Required

Default

Description

column

string | Expression

true

The name of the column or Expression with which to constrain the query.

operator

any

false

The operator to use for the constraint (i.e. "=", "<", ">=", etc.). A value can be passed as the operator and the value left null as a shortcut for equals (e.g. where( "column", 1 ) == where( "column", "=", 1 ) ).

value

any

false

The value with which to constrain the column. An Expression can be passed as well.

combinator

string

false

"and"

The boolean combinator for the clause. Valid options are "and" or "or". Avoid passing this parameter explicitly. Where possible use the andHaving and orHaving methods instead.

Adds a having clause to a query.

QueryBuilder
query.from( "users" )
    .groupBy( "email" )
    .having( "email", ">", 1 );
MySQL
SELECT *
FROM `users`
GROUP BY `email`
HAVING `email` > ?

Expressions can be used in place of the column or the value.

QueryBuilder
query.from( "users" )
    .groupBy( "email" )
    .having( query.raw( "COUNT(email)" ), ">", 1 );
MySQL
SELECT *
FROM `users`
GROUP BY `email`
HAVING COUNT(email) > ?

Loading...

Locks

qb includes a few methods to help you lock certain rows when executing select statements.

Note: For locks to work properly, they must be nested inside a transaction. qb does not handle any of the transaction lifecycle for you.

sharedLock

Name

Type

Required

Default

Description

No arguments

A shared lock prevents the selected rows from being modified until your transaction is committed.

query.from( "users" )
    .where( "id", 1 )
    .sharedLock();
SELECT *
FROM `users`
WHERE `id` = ?
LOCK IN SHARE MODE
SELECT *
FROM [users] WITH (ROWLOCK,HOLDLOCK)
WHERE [id] = ?
SELECT *
FROM "users"
WHERE "id" = ?
FOR SHARE
LOCK TABLE "USERS"
IN SHARE MODE NOWAIT;

SELECT *
FROM "USERS"
WHERE "ID" = ?

lockForUpdate

Name
Type
Required
Default
Description

skipLocked

Boolean

false

false

A lock for update lock prevents the selected rows from being modified or selected with another shared lock until your transaction is committed.

The main difference between a sharedLock and lockForUpdate is that a lockForUpdate prevents other reads or selects as well as updates.

query.from( "users" )
    .where( "id", 1 )
    .lockForUpdate();
SELECT *
FROM `users`
WHERE `id` = ?
FOR UPDATE
SELECT *
FROM [users] WITH (ROWLOCK,UPDLOCK,HOLDLOCK)
WHERE [id] = ?
SELECT *
FROM "users"
WHERE "id" = ?
FOR UPDATE
SELECT *
FROM "USERS"
WHERE "ID" = ?
FOR UPDATE

When using the skipLocked flag, the query will skip over locked records and only return and lock available records.

query.from( "users" )
    .where( "id", 1 )
    .lockForUpdate( skipLocked = true )
    .orderBy( "id" )
    .limit( 5 );
SELECT *
FROM `users`
WHERE `id` = ?
ORDER BY `id`
LIMIT 5
FOR UPDATE SKIP LOCKED
SELECT TOP 5 *
FROM [users] WITH (ROWLOCK,UPDLOCK,HOLDLOCK,READPAST)
WHERE [id] = ?
ORDER BY [id]
SELECT *
FROM "users"
WHERE "id" = ?
ORDER BY "id"
LIMIT 1
FOR UPDATE SKIP LOCKED

noLock

Name

Type

Required

Default

Description

No arguments

noLock will instruct your grammar to ignore any shared locks when executing the query.

Currently this only makes a difference in SQL Server grammars.

query.from( "users" )
    .where( "id", 1 )
    .noLock();
SELECT *
FROM [users] WITH (NOLOCK)
WHERE [id] = ?

lock

Name

Type

Required

Default

Description

value

string

true

The custom lock directive to add to the query.

The lock method will allow you to add a custom lock directive to your query. Think of it as the raw method for lock directives.

These lock directives vary from grammar to grammar.

clearLock

Name

Type

Required

Default

Description

No arguments

Clears any lock directive on the query.

Loading...

Loading...

Loading...

Loading...

Loading...