Select Builder
The select builder allows you to create SELECT queries,
to fetch data from your database.
.select(...columns:Pointers[])
The select builder factory takes as argument a list of pointers with or without
alias. You can also use any aggregation function.
const {toJson} = require('ship-hold-querybuilder');
sh
.select('posts.post_id', 'published_at', {
as: 'author',
value: sh.select(toJson('"users".*'))
.from('users')
.where('users.user_id', '"posts"."user_id"')
.noop()
})
.from('posts')
.build();
You can also use it without any argument: the wildcard sign *
will be used instead.
You can also call .select(...args)
as a method of an existing select builder
with the same effect (if you only know a part of the column list later, when your builder has already been instantiated)
.from(...tables:Pointers[])
This method allows you to specify a list of tables. It takes the same kind of arguments as the select
method.
sh
.select()
.from('posts', 'public.users', {
value: sh.select().from('comments'),
as: 'comzz'
})
.build();
If you use a sub query as a table expression, SQL syntax enforces you to use an alias
Joins
There are few methods to join table together. They take the same arguments as the from method.
You usually call the on method after you have joined a table to apply a join condition but you can
also pass a leftOperand and a rightOperand for usual join equality condition
.join(table: Pointer, operator?, rightOperand?)
Performs an INNER JOIN
.leftJoin(table: Pointer, leftOperand?, rightOperand?)
Performs a LEFT OUTER JOIN
.rightJoin(table: Pointer, leftOperand?, rightOperand?)
Performs a RIGHT OUTER JOIN
You can of course combine multiple joins.
.on(leftOperand: Pointer, operator ?: Operator, rightOperand?: value)
This method returns a proxy of a condition builder which will be revoked whenever you call a method which does not belong to the condition builder.
See conditions builder for more details. You use it to create a join condition on a particular join
sh
.select()
.from('posts')
.leftJoin('users')
.on('posts.user_id', '"users"."user_id"')
.build();
sh
.select()
.from('posts')
.leftJoin('users', 'posts.user_id', '"users"."user_id"')
.build();
sh
.select()
.from('posts')
.join({
value: sh
.select()
.from('users')
.where('users.first_name', 'Laurent')
.noop(),
as: 'Laurents'
})
.on('posts.user_id', '"Laurents".user_id')
.and('published_at', '>', new Date(2010))
.build();
Group
You can decide to group some rows and eventually filter those groups.
.groupBy(...columns:string[])
This method allows you to create a group by clause.
Just pass column names you wish to group by
const {count} = require('ship-hold-querybuilder');
sh
.select(count('*'), 'user_id')
.from('posts')
.groupBy('user_id')
.build();
.having(leftOperand: Pointer, operator?, rightOperand?)
This method allows you to apply a filter on grouped rows. It defers from the where clause which
applies the filter before the groups are formed. In the same way as the the where method it returns a
proxied condition builder so you can chain conditions
const {count} = require('ship-hold-querybuilder');
sh
.select(count('*'), 'user_id')
.from('posts')
.groupBy('user_id')
.having('posts.count', '>', 3)
.build();
.where(leftOperand, ?operator, ?rightOperand)
This method returns a proxy of a condition builder which will be revoked whenever you call a method which does not belong to the condition builder.
See conditions builder for more details. You use it to create where clause in your select query
sh
.select()
.from('posts')
.where('posts.user_id', 42)
.and('published_at', '>', new Date(2010, 1, 1))
.build();
.orderBy(column: string, direction?: SortDirection)
This method will let you order the result rows according to a given column. The second argument will give the direction:
it can be 'desc'
either 'asc'
. If no direction is provided the direction will be ascendant.
sh
.select()
.from('posts')
.orderBy('published_at', 'desc')
.build();
You can combine different order by clauses by calling multiple times the orderBy
method.
To have your rows paginated you have to combine the SQL clauses LIMIT and OFFSET.
In ship hold this is controlled by the limit
method
.limit(size: number, offset?: number)
The first argument will be the size of you page whereas the second one will be the number of row skipped.
If you don't provide a second argument, no row will be skipped
sh
.select()
.from('posts')
.orderBy('published_at', 'desc')
.limit(10, 20)
.build();
If you want to have consistent pagination result, you have to order your result. Otherwise the database
may return different results depending on the query plan it has chosen.