# Subqueries
Subqueries can be written just like in knex: by passing a function in place of a value. A bunch of query building methods accept a function. See the knex.js documentation or just try it out. A function is accepted in most places you would expect. You can also pass QueryBuilder instances or knex queries instead of functions.
Using a function:
const peopleOlderThanAverage = await Person.query().where(
'age',
'>',
builder => {
builder.avg('age').from('persons');
}
);
console.log(peopleOlderThanAverage);
Using a QueryBuilder:
const peopleOlderThanAverage = await Person.query().where(
'age',
'>',
Person.query().avg('age')
);
console.log(peopleOlderThanAverage);
You can use ref to reference the parent query in subqueries:
const { ref } = require('objection');
const peopleWithPetCount = await Person.query().select([
'persons.*',
Pet.query()
.where('ownerId', ref('persons.id'))
.count()
.as('petCount')
]);
console.log(peopleWithPetCount[4].petCount);
The above query can also be written using the relatedQuery (assuming a relation pets
has been defined for Person
):
const peopleWithPetCount = await Person.query().select([
'persons.*',
Person.relatedQuery('pets')
.count()
.as('petCount')
]);
console.log(peopleWithPetCount[4].petCount);