Skip to content

Commit

Permalink
feat(query-builder): add withinGroupOrderBy method to aggregate funct…
Browse files Browse the repository at this point in the history
…ion builder

kysely-org#781
  • Loading branch information
Dev K0te committed Jun 7, 2024
1 parent 24d3846 commit c81d766
Showing 1 changed file with 41 additions and 3 deletions.
44 changes: 41 additions & 3 deletions src/query-builder/aggregate-function-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '../expression/expression.js'
import {
ReferenceExpression,
StringReference,
SimpleReferenceExpression,
} from '../parser/reference-parser.js'
import {
ComparisonOperatorExpression,
Expand All @@ -22,7 +22,6 @@ import {
} from '../parser/binary-operation-parser.js'
import { SqlBool } from '../util/type-utils.js'
import { ExpressionOrFactory } from '../parser/expression-parser.js'
import { DynamicReferenceBuilder } from '../dynamic/dynamic-reference-builder.js'
import {
OrderByDirectionExpression,
parseOrderBy,
Expand Down Expand Up @@ -126,7 +125,7 @@ export class AggregateFunctionBuilder<DB, TB extends keyof DB, O = unknown>
* inner join "pet" ON "pet"."owner_id" = "person"."id"
* ```
*/
orderBy<OE extends StringReference<DB, TB> | DynamicReferenceBuilder<any>>(
orderBy<OE extends SimpleReferenceExpression<DB, TB>>(
orderBy: OE,
direction?: OrderByDirectionExpression,
): AggregateFunctionBuilder<DB, TB, O> {
Expand All @@ -139,6 +138,45 @@ export class AggregateFunctionBuilder<DB, TB extends keyof DB, O = unknown>
})
}

/**
* Adds a `withing group` clause with a nested `order by` clause after the function.
*
* ### Examples
*
* Most frequent person name:
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select((eb) => [
* eb.fn
* .agg<string>('mode')
* .withinGroupOrderBy('person.name')
* .as('most_frequent_name')
* ])
* .executeTakeFirstOrThrow()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select mode() within group (order by "person"."name") as "most_frequent_name"
* from "person"
* ```
*/
withinGroupOrderBy<OE extends SimpleReferenceExpression<DB, TB>>(
orderBy: OE,
direction?: OrderByDirectionExpression,
): AggregateFunctionBuilder<DB, TB, O> {
return new AggregateFunctionBuilder({
...this.#props,
aggregateFunctionNode: AggregateFunctionNode.cloneWithWithinGroup(
this.#props.aggregateFunctionNode,
parseOrderBy([orderBy, direction]),
),
})
}

/**
* Adds a `filter` clause with a nested `where` clause after the function.
*
Expand Down

0 comments on commit c81d766

Please sign in to comment.