kysely
    Preparing search index...

    Class UpdateQueryBuilder<DB, UT, TB, O>

    Type Parameters

    • DB
    • UT extends keyof DB
    • TB extends keyof DB
    • O

    Implements

    Index

    Constructors

    Methods

    • Asserts that query's output row type equals the given type T.

      This method can be used to simplify excessively complex types to make TypeScript happy and much faster.

      Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much for TypeScript and you get errors like this:

      error TS2589: Type instantiation is excessively deep and possibly infinite.
      

      In these case you can often use this method to help TypeScript a little bit. When you use this method to assert the output type of a query, Kysely can drop the complex output type that consists of multiple nested helper types and replace it with the simple asserted type.

      Using this method doesn't reduce type safety at all. You have to pass in a type that is structurally equal to the current type.

      import type { PersonUpdate, PetUpdate, Species } from 'type-editor' // imaginary module

      const person = {
      id: 1,
      gender: 'other',
      } satisfies PersonUpdate

      const pet = {
      name: 'Fluffy',
      } satisfies PetUpdate

      const result = await db
      .with('updated_person', (qb) => qb
      .updateTable('person')
      .set(person)
      .where('id', '=', person.id)
      .returning('first_name')
      .$assertType<{ first_name: string }>()
      )
      .with('updated_pet', (qb) => qb
      .updateTable('pet')
      .set(pet)
      .where('owner_id', '=', person.id)
      .returning(['name as pet_name', 'species'])
      .$assertType<{ pet_name: string, species: Species }>()
      )
      .selectFrom(['updated_person', 'updated_pet'])
      .selectAll()
      .executeTakeFirstOrThrow()

      Type Parameters

      • T

      Returns O extends T
          ? UpdateQueryBuilder<DB, UT, TB, T>
          : KyselyTypeError<
              "$assertType() call failed: The type passed in is not equal to the output type of the query.",
          >

    • Simply calls the provided function passing this as the only argument. $call returns what the provided function returns.

      If you want to conditionally call a method on this, see the $if method.

      The next example uses a helper function log to log a query:

      import type { Compilable } from 'kysely'
      import type { PersonUpdate } from 'type-editor' // imaginary module

      function log<T extends Compilable>(qb: T): T {
      console.log(qb.compile())
      return qb
      }

      const values = {
      first_name: 'John',
      } satisfies PersonUpdate

      db.updateTable('person')
      .set(values)
      .$call(log)
      .execute()

      Type Parameters

      • T

      Parameters

      • func: (qb: this) => T

      Returns T

    • Call func(this) if condition is true.

      This method is especially handy with optional selects. Any returning or returningAll method calls add columns as optional fields to the output type when called inside the func callback. This is because we can't know if those selections were actually made before running the code.

      You can also call any other methods inside the callback.

      import type { PersonUpdate } from 'type-editor' // imaginary module

      async function updatePerson(id: number, updates: PersonUpdate, returnLastName: boolean) {
      return await db
      .updateTable('person')
      .set(updates)
      .where('id', '=', id)
      .returning(['id', 'first_name'])
      .$if(returnLastName, (qb) => qb.returning('last_name'))
      .executeTakeFirstOrThrow()
      }

      Any selections added inside the if callback will be added as optional fields to the output type since we can't know if the selections were actually made before running the code. In the example above the return type of the updatePerson function is:

      Promise<{
      id: number
      first_name: string
      last_name?: string
      }>

      Type Parameters

      • O2

      Parameters

      Returns O2 extends UpdateResult
          ? UpdateQueryBuilder<DB, UT, TB, UpdateResult>
          : O2 extends O & E
              ? UpdateQueryBuilder<DB, UT, TB, O & Partial<E>>
              : UpdateQueryBuilder<DB, UT, TB, Partial<O2>>

    • Narrows (parts of) the output type of the query.

      Kysely tries to be as type-safe as possible, but in some cases we have to make compromises for better maintainability and compilation performance. At present, Kysely doesn't narrow the output type of the query based on set input when using where and/or returning or returningAll.

      This utility method is very useful for these situations, as it removes unncessary runtime assertion/guard code. Its input type is limited to the output type of the query, so you can't add a column that doesn't exist, or change a column's type to something that doesn't exist in its union type.

      Turn this code:

      import type { Person } from 'type-editor' // imaginary module

      const id = 1
      const now = new Date().toISOString()

      const person = await db.updateTable('person')
      .set({ deleted_at: now })
      .where('id', '=', id)
      .where('nullable_column', 'is not', null)
      .returningAll()
      .executeTakeFirstOrThrow()

      if (isWithNoNullValue(person)) {
      functionThatExpectsPersonWithNonNullValue(person)
      }

      function isWithNoNullValue(person: Person): person is Person & { nullable_column: string } {
      return person.nullable_column != null
      }

      Into this:

      import type { NotNull } from 'kysely'

      const id = 1
      const now = new Date().toISOString()

      const person = await db.updateTable('person')
      .set({ deleted_at: now })
      .where('id', '=', id)
      .where('nullable_column', 'is not', null)
      .returningAll()
      .$narrowType<{ deleted_at: Date; nullable_column: NotNull }>()
      .executeTakeFirstOrThrow()

      functionThatExpectsPersonWithNonNullValue(person)

      Type Parameters

      • T

      Returns UpdateQueryBuilder<DB, UT, TB, NarrowPartial<O, T>>

    • Executes query with explain statement before the main query.

      const explained = await db
      .selectFrom('person')
      .where('gender', '=', 'female')
      .selectAll()
      .explain('json')

      The generated SQL (MySQL):

      explain format=json select * from `person` where `gender` = ?
      

      You can also execute explain analyze statements.

      import { sql } from 'kysely'

      const explained = await db
      .selectFrom('person')
      .where('gender', '=', 'female')
      .selectAll()
      .explain('json', sql`analyze`)

      The generated SQL (PostgreSQL):

      explain (analyze, format json) select * from "person" where "gender" = $1
      

      Type Parameters

      • ER extends Record<string, any> = Record<string, any>

      Parameters

      Returns Promise<ER[]>

    • Adds a from clause to the update query.

      This is supported only on some databases like PostgreSQL.

      The API is the same as QueryCreator.selectFrom.

      db.updateTable('person')
      .from('pet')
      .set((eb) => ({
      first_name: eb.ref('pet.name')
      }))
      .whereRef('pet.owner_id', '=', 'person.id')

      The generated SQL (PostgreSQL):

      update "person"
      set "first_name" = "pet"."name"
      from "pet"
      where "pet"."owner_id" = "person"."id"

      Type Parameters

      • TE extends
            | string
            | AliasedExpression<any, any>
            | AliasedDynamicTableBuilder<any, any>
            | AliasedExpressionFactory<DB, TB>

      Parameters

      Returns UpdateQueryBuilder<From<DB, TE>, UT, FromTables<DB, TB, TE>, O>

    • Adds a from clause to the update query.

      This is supported only on some databases like PostgreSQL.

      The API is the same as QueryCreator.selectFrom.

      db.updateTable('person')
      .from('pet')
      .set((eb) => ({
      first_name: eb.ref('pet.name')
      }))
      .whereRef('pet.owner_id', '=', 'person.id')

      The generated SQL (PostgreSQL):

      update "person"
      set "first_name" = "pet"."name"
      from "pet"
      where "pet"."owner_id" = "person"."id"

      Type Parameters

      • TE extends
            | string
            | AliasedExpression<any, any>
            | AliasedDynamicTableBuilder<any, any>
            | AliasedExpressionFactory<DB, TB>

      Parameters

      • table: TE[]

      Returns UpdateQueryBuilder<From<DB, TE>, UT, FromTables<DB, TB, TE>, O>

    • Joins another table to the query using an inner join.

      Simple usage by providing a table name and two columns to join:

      const result = await db
      .selectFrom('person')
      .innerJoin('pet', 'pet.owner_id', 'person.id')
      // `select` needs to come after the call to `innerJoin` so
      // that you can select from the joined table.
      .select(['person.id', 'pet.name'])
      .execute()

      result[0].id
      result[0].name

      The generated SQL (PostgreSQL):

      select "person"."id", "pet"."name"
      from "person"
      inner join "pet"
      on "pet"."owner_id" = "person"."id"

      You can give an alias for the joined table like this:

      await db.selectFrom('person')
      .innerJoin('pet as p', 'p.owner_id', 'person.id')
      .where('p.name', '=', 'Doggo')
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join "pet" as "p"
      on "p"."owner_id" = "person"."id"
      where "p".name" = $1

      You can provide a function as the second argument to get a join builder for creating more complex joins. The join builder has a bunch of on* methods for building the on clause of the join. There's basically an equivalent for every where method (on, onRef, onExists etc.). You can do all the same things with the on method that you can with the corresponding where method. See the where method documentation for more examples.

      await db.selectFrom('person')
      .innerJoin(
      'pet',
      (join) => join
      .onRef('pet.owner_id', '=', 'person.id')
      .on('pet.name', '=', 'Doggo')
      )
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join "pet"
      on "pet"."owner_id" = "person"."id"
      and "pet"."name" = $1

      You can join a subquery by providing a select query (or a callback) as the first argument:

      await db.selectFrom('person')
      .innerJoin(
      db.selectFrom('pet')
      .select(['owner_id', 'name'])
      .where('name', '=', 'Doggo')
      .as('doggos'),
      'doggos.owner_id',
      'person.id',
      )
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join (
      select "owner_id", "name"
      from "pet"
      where "name" = $1
      ) as "doggos"
      on "doggos"."owner_id" = "person"."id"

      Type Parameters

      • TE extends
            | string
            | AliasedExpression<any, any>
            | AliasedDynamicTableBuilder<any, any>
            | AliasedExpressionFactory<DB, TB>
      • K1 extends string
      • K2 extends string

      Parameters

      Returns UpdateQueryBuilderWithInnerJoin<DB, UT, TB, O, TE>

    • Joins another table to the query using an inner join.

      Simple usage by providing a table name and two columns to join:

      const result = await db
      .selectFrom('person')
      .innerJoin('pet', 'pet.owner_id', 'person.id')
      // `select` needs to come after the call to `innerJoin` so
      // that you can select from the joined table.
      .select(['person.id', 'pet.name'])
      .execute()

      result[0].id
      result[0].name

      The generated SQL (PostgreSQL):

      select "person"."id", "pet"."name"
      from "person"
      inner join "pet"
      on "pet"."owner_id" = "person"."id"

      You can give an alias for the joined table like this:

      await db.selectFrom('person')
      .innerJoin('pet as p', 'p.owner_id', 'person.id')
      .where('p.name', '=', 'Doggo')
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join "pet" as "p"
      on "p"."owner_id" = "person"."id"
      where "p".name" = $1

      You can provide a function as the second argument to get a join builder for creating more complex joins. The join builder has a bunch of on* methods for building the on clause of the join. There's basically an equivalent for every where method (on, onRef, onExists etc.). You can do all the same things with the on method that you can with the corresponding where method. See the where method documentation for more examples.

      await db.selectFrom('person')
      .innerJoin(
      'pet',
      (join) => join
      .onRef('pet.owner_id', '=', 'person.id')
      .on('pet.name', '=', 'Doggo')
      )
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join "pet"
      on "pet"."owner_id" = "person"."id"
      and "pet"."name" = $1

      You can join a subquery by providing a select query (or a callback) as the first argument:

      await db.selectFrom('person')
      .innerJoin(
      db.selectFrom('pet')
      .select(['owner_id', 'name'])
      .where('name', '=', 'Doggo')
      .as('doggos'),
      'doggos.owner_id',
      'person.id',
      )
      .selectAll()
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      inner join (
      select "owner_id", "name"
      from "pet"
      where "name" = $1
      ) as "doggos"
      on "doggos"."owner_id" = "person"."id"

      Type Parameters

      Parameters

      • table: TE
      • callback: FN

      Returns UpdateQueryBuilderWithInnerJoin<DB, UT, TB, O, TE>

    • Type Parameters

      • OE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>

      This is only supported by some dialects like MySQL or SQLite with SQLITE_ENABLE_UPDATE_DELETE_LIMIT.

    • Type Parameters

      • OE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>

      Parameters

      • exprs: readonly OE[]

      Returns UpdateQueryBuilder<DB, UT, TB, O>

      This is only supported by some dialects like MySQL or SQLite with SQLITE_ENABLE_UPDATE_DELETE_LIMIT.

      It does ~2-2.6x more compile-time instantiations compared to multiple chained orderBy(expr, modifiers?) calls (in order by clauses with reasonable item counts), and has broken autocompletion.

    • Type Parameters

      • OE extends
            | `${string} desc`
            | `${string} asc`
            | `${string}.${string} desc`
            | `${string}.${string} asc`

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>

      This is only supported by some dialects like MySQL or SQLite with SQLITE_ENABLE_UPDATE_DELETE_LIMIT.

      It does ~2.9x more compile-time instantiations compared to a orderBy(expr, direction) call.

    • Type Parameters

      • OE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>

      This is only supported by some dialects like MySQL or SQLite with SQLITE_ENABLE_UPDATE_DELETE_LIMIT.

      Use orderBy(expr, (ob) => ...) instead.

    • Allows you to return data from modified rows.

      On supported databases like MS SQL Server (MSSQL), this method can be chained to insert, update, delete and merge queries to return data.

      Also see the outputAll method.

      Return one column:

      const { id } = await db
      .insertInto('person')
      .output('inserted.id')
      .values({
      first_name: 'Jennifer',
      last_name: 'Aniston',
      gender: 'female',
      })
      .executeTakeFirstOrThrow()

      The generated SQL (MSSQL):

      insert into "person" ("first_name", "last_name", "gender")
      output "inserted"."id"
      values (@1, @2, @3)

      Return multiple columns:

      const { old_first_name, old_last_name, new_first_name, new_last_name } = await db
      .updateTable('person')
      .set({ first_name: 'John', last_name: 'Doe' })
      .output([
      'deleted.first_name as old_first_name',
      'deleted.last_name as old_last_name',
      'inserted.first_name as new_first_name',
      'inserted.last_name as new_last_name',
      ])
      .where('created_at', '<', new Date())
      .executeTakeFirstOrThrow()

      The generated SQL (MSSQL):

      update "person"
      set "first_name" = @1, "last_name" = @2
      output "deleted"."first_name" as "old_first_name",
      "deleted"."last_name" as "old_last_name",
      "inserted"."first_name" as "new_first_name",
      "inserted"."last_name" as "new_last_name"
      where "created_at" < @3

      Return arbitrary expressions:

      importsql } from 'kysely'

      const { full_name } = await db
      .deleteFrom('person')
      .output((eb) => sql<string>`concat(${eb.ref('deleted.first_name')}, ' ', ${eb.ref('deleted.last_name')})`.as('full_name'))
      .where('created_at', '<', new Date())
      .executeTakeFirstOrThrow()

      The generated SQL (MSSQL):

      delete from "person"
      output concat("deleted"."first_name", ' ', "deleted"."last_name") as "full_name"
      where "created_at" < @1

      Return the action performed on the row:

      await db
      .mergeInto('person')
      .using('pet', 'pet.owner_id', 'person.id')
      .whenMatched()
      .thenDelete()
      .whenNotMatched()
      .thenInsertValues({
      first_name: 'John',
      last_name: 'Doe',
      gender: 'male'
      })
      .output([
      'inserted.id as inserted_id',
      'deleted.id as deleted_id',
      ])
      .execute()

      The generated SQL (MSSQL):

      merge into "person"
      using "pet" on "pet"."owner_id" = "person"."id"
      when matched then delete
      when not matched then
      insert ("first_name", "last_name", "gender")
      values (@1, @2, @3)
      output "inserted"."id" as "inserted_id", "deleted"."id" as "deleted_id"

      Type Parameters

      • OE extends
            | AliasedExpression<any, any>
            | `deleted.${string}`
            | `inserted.${string}`
            | `deleted.${string} as ${string}`
            | `inserted.${string} as ${string}`
            | AliasedExpressionFactory<
                OutputDatabase<DB, UT, OutputPrefix>,
                OutputPrefix,
            >

      Parameters

      • selections: readonly OE[]

      Returns UpdateQueryBuilder<
          DB,
          UT,
          TB,
          ReturningRow<DB, TB, O, SelectExpressionFromOutputExpression<OE>>,
      >

    • Type Parameters

      Parameters

      • callback: CB

      Returns UpdateQueryBuilder<
          DB,
          UT,
          TB,
          ReturningRow<DB, TB, O, SelectExpressionFromOutputCallback<CB>>,
      >

    • Type Parameters

      • OE extends
            | AliasedExpression<any, any>
            | `deleted.${string}`
            | `inserted.${string}`
            | `deleted.${string} as ${string}`
            | `inserted.${string} as ${string}`
            | AliasedExpressionFactory<
                OutputDatabase<DB, TB, OutputPrefix>,
                OutputPrefix,
            >

      Parameters

      • selection: OE

      Returns UpdateQueryBuilder<
          DB,
          UT,
          TB,
          ReturningRow<DB, TB, O, SelectExpressionFromOutputExpression<OE>>,
      >

    • Sets the values to update for an update query.

      This method takes an object whose keys are column names and values are values to update. In addition to the column's type, the values can be any expressions such as raw sql snippets or select queries.

      This method also accepts a callback that returns the update object. The callback takes an instance of ExpressionBuilder as its only argument. The expression builder can be used to create arbitrary update expressions.

      The return value of an update query is an instance of UpdateResult. You can use the returning method on supported databases to get out the updated rows.

      Update a row in person table:

      const result = await db
      .updateTable('person')
      .set({
      first_name: 'Jennifer',
      last_name: 'Aniston'
      })
      .where('id', '=', 1)
      .executeTakeFirst()

      The generated SQL (PostgreSQL):

      update "person" set "first_name" = $1, "last_name" = $2 where "id" = $3
      

      As always, you can provide a callback to the set method to get access to an expression builder:

      const result = await db
      .updateTable('person')
      .set((eb) => ({
      age: eb('age', '+', 1),
      first_name: eb.selectFrom('pet').select('name').limit(1),
      last_name: 'updated',
      }))
      .where('id', '=', 1)
      .executeTakeFirst()

      The generated SQL (PostgreSQL):

      update "person"
      set
      "first_name" = (select "name" from "pet" limit $1),
      "age" = "age" + $2,
      "last_name" = $3
      where
      "id" = $4

      If you provide two arguments the first one is interpreted as the column (or other target) and the second as the value:

      import { sql } from 'kysely'

      const result = await db
      .updateTable('person')
      .set('first_name', 'Foo')
      // As always, both arguments can be arbitrary expressions or
      // callbacks that give you access to an expression builder:
      .set(sql<string>`address['postalCode']`, (eb) => eb.val('61710'))
      .where('id', '=', 1)
      .executeTakeFirst()

      On PostgreSQL you can chain returning to the query to get the updated rows' columns (or any other expression) as the return value:

      const row = await db
      .updateTable('person')
      .set({
      first_name: 'Jennifer',
      last_name: 'Aniston'
      })
      .where('id', '=', 1)
      .returning('id')
      .executeTakeFirstOrThrow()

      row.id

      The generated SQL (PostgreSQL):

      update "person" set "first_name" = $1, "last_name" = $2 where "id" = $3 returning "id"
      

      In addition to primitives, the values can arbitrary expressions including raw sql snippets or subqueries:

      import { sql } from 'kysely'

      const result = await db
      .updateTable('person')
      .set(({ selectFrom, ref, fn, eb }) => ({
      first_name: selectFrom('person').select('first_name').limit(1),
      middle_name: ref('first_name'),
      age: eb('age', '+', 1),
      last_name: sql<string>`${'Ani'} || ${'ston'}`,
      }))
      .where('id', '=', 1)
      .executeTakeFirst()

      console.log(result.numUpdatedRows)

      The generated SQL (PostgreSQL):

      update "person" set
      "first_name" = (select "first_name" from "person" limit $1),
      "middle_name" = "first_name",
      "age" = "age" + $2,
      "last_name" = $3 || $4
      where "id" = $5

      MySQL allows you to join tables directly to the "main" table and update rows of all joined tables. This is possible by passing all tables to the updateTable method as a list and adding the ON conditions as WHERE statements. You can then use the set(column, value) variant to update columns using table qualified names.

      The UpdateQueryBuilder also has innerJoin etc. join methods, but those can only be used as part of a PostgreSQL update set from join query. Due to type complexity issues, we unfortunately can't make the same methods work in both cases.

      const result = await db
      .updateTable(['person', 'pet'])
      .set('person.first_name', 'Updated person')
      .set('pet.name', 'Updated doggo')
      .whereRef('person.id', '=', 'pet.owner_id')
      .where('person.id', '=', 1)
      .executeTakeFirst()

      The generated SQL (MySQL):

      update
      `person`,
      `pet`
      set
      `person`.`first_name` = ?,
      `pet`.`name` = ?
      where
      `person`.`id` = `pet`.`owner_id`
      and `person`.`id` = ?

      Parameters

      • update: UpdateObjectExpression<DB, TB, UT>

      Returns UpdateQueryBuilder<DB, UT, TB, O>

    • Sets the values to update for an update query.

      This method takes an object whose keys are column names and values are values to update. In addition to the column's type, the values can be any expressions such as raw sql snippets or select queries.

      This method also accepts a callback that returns the update object. The callback takes an instance of ExpressionBuilder as its only argument. The expression builder can be used to create arbitrary update expressions.

      The return value of an update query is an instance of UpdateResult. You can use the returning method on supported databases to get out the updated rows.

      Update a row in person table:

      const result = await db
      .updateTable('person')
      .set({
      first_name: 'Jennifer',
      last_name: 'Aniston'
      })
      .where('id', '=', 1)
      .executeTakeFirst()

      The generated SQL (PostgreSQL):

      update "person" set "first_name" = $1, "last_name" = $2 where "id" = $3
      

      As always, you can provide a callback to the set method to get access to an expression builder:

      const result = await db
      .updateTable('person')
      .set((eb) => ({
      age: eb('age', '+', 1),
      first_name: eb.selectFrom('pet').select('name').limit(1),
      last_name: 'updated',
      }))
      .where('id', '=', 1)
      .executeTakeFirst()

      The generated SQL (PostgreSQL):

      update "person"
      set
      "first_name" = (select "name" from "pet" limit $1),
      "age" = "age" + $2,
      "last_name" = $3
      where
      "id" = $4

      If you provide two arguments the first one is interpreted as the column (or other target) and the second as the value:

      import { sql } from 'kysely'

      const result = await db
      .updateTable('person')
      .set('first_name', 'Foo')
      // As always, both arguments can be arbitrary expressions or
      // callbacks that give you access to an expression builder:
      .set(sql<string>`address['postalCode']`, (eb) => eb.val('61710'))
      .where('id', '=', 1)
      .executeTakeFirst()

      On PostgreSQL you can chain returning to the query to get the updated rows' columns (or any other expression) as the return value:

      const row = await db
      .updateTable('person')
      .set({
      first_name: 'Jennifer',
      last_name: 'Aniston'
      })
      .where('id', '=', 1)
      .returning('id')
      .executeTakeFirstOrThrow()

      row.id

      The generated SQL (PostgreSQL):

      update "person" set "first_name" = $1, "last_name" = $2 where "id" = $3 returning "id"
      

      In addition to primitives, the values can arbitrary expressions including raw sql snippets or subqueries:

      import { sql } from 'kysely'

      const result = await db
      .updateTable('person')
      .set(({ selectFrom, ref, fn, eb }) => ({
      first_name: selectFrom('person').select('first_name').limit(1),
      middle_name: ref('first_name'),
      age: eb('age', '+', 1),
      last_name: sql<string>`${'Ani'} || ${'ston'}`,
      }))
      .where('id', '=', 1)
      .executeTakeFirst()

      console.log(result.numUpdatedRows)

      The generated SQL (PostgreSQL):

      update "person" set
      "first_name" = (select "first_name" from "person" limit $1),
      "middle_name" = "first_name",
      "age" = "age" + $2,
      "last_name" = $3 || $4
      where "id" = $5

      MySQL allows you to join tables directly to the "main" table and update rows of all joined tables. This is possible by passing all tables to the updateTable method as a list and adding the ON conditions as WHERE statements. You can then use the set(column, value) variant to update columns using table qualified names.

      The UpdateQueryBuilder also has innerJoin etc. join methods, but those can only be used as part of a PostgreSQL update set from join query. Due to type complexity issues, we unfortunately can't make the same methods work in both cases.

      const result = await db
      .updateTable(['person', 'pet'])
      .set('person.first_name', 'Updated person')
      .set('pet.name', 'Updated doggo')
      .whereRef('person.id', '=', 'pet.owner_id')
      .where('person.id', '=', 1)
      .executeTakeFirst()

      The generated SQL (MySQL):

      update
      `person`,
      `pet`
      set
      `person`.`first_name` = ?,
      `pet`.`name` = ?
      where
      `person`.`id` = `pet`.`owner_id`
      and `person`.`id` = ?

      Type Parameters

      • RE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, UT, any>

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>

    • Executes the query and streams the rows.

      The optional argument chunkSize defines how many rows to fetch from the database at a time. It only affects some dialects like PostgreSQL that support it.

      const stream = db
      .selectFrom('person')
      .select(['first_name', 'last_name'])
      .where('gender', '=', 'other')
      .stream()

      for await (const person of stream) {
      console.log(person.first_name)

      if (person.last_name === 'Something') {
      // Breaking or returning before the stream has ended will release
      // the database connection and invalidate the stream.
      break
      }
      }

      Parameters

      • chunkSize: number = 100

      Returns AsyncIterableIterator<O>

    • Changes an update query into a update top query.

      top clause is only supported by some dialects like MS SQL Server.

      Update the first row:

      await db.updateTable('person')
      .top(1)
      .set({ first_name: 'Foo' })
      .where('age', '>', 18)
      .executeTakeFirstOrThrow()

      The generated SQL (MS SQL Server):

      update top(1) "person" set "first_name" = @1 where "age" > @2
      

      Update the 50% first rows:

      await db.updateTable('person')
      .top(50, 'percent')
      .set({ first_name: 'Foo' })
      .where('age', '>', 18)
      .executeTakeFirstOrThrow()

      The generated SQL (MS SQL Server):

      update top(50) percent "person" set "first_name" = @1 where "age" > @2
      

      Parameters

      • expression: number | bigint
      • Optionalmodifiers: "percent"

      Returns UpdateQueryBuilder<DB, UT, TB, O>

    • Adds a where expression to the query.

      Calling this method multiple times will combine the expressions using and.

      Also see whereRef

      where method calls are combined with AND:

      const person = await db
      .selectFrom('person')
      .selectAll()
      .where('first_name', '=', 'Jennifer')
      .where('age', '>', 40)
      .executeTakeFirst()

      The generated SQL (PostgreSQL):

      select * from "person" where "first_name" = $1 and "age" > $2
      

      Operator can be any supported operator or if the typings don't support it you can always use:

      import { sql } from 'kysely'

      sql`your operator`

      Find multiple items using a list of identifiers:

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where('id', 'in', [1, 2, 3])
      .execute()

      The generated SQL (PostgreSQL):

      select * from "person" where "id" in ($1, $2, $3)
      

      You can use the and function to create a simple equality filter using an object

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where((eb) => eb.and({
      first_name: 'Jennifer',
      last_name: eb.ref('first_name')
      }))
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      where (
      "first_name" = $1
      and "last_name" = "first_name"
      )

      To combine conditions using OR, you can use the expression builder. There are two ways to create OR expressions. Both are shown in this example:

      const persons = await db
      .selectFrom('person')
      .selectAll()
      // 1. Using the `or` method on the expression builder:
      .where((eb) => eb.or([
      eb('first_name', '=', 'Jennifer'),
      eb('first_name', '=', 'Sylvester')
      ]))
      // 2. Chaining expressions using the `or` method on the
      // created expressions:
      .where((eb) =>
      eb('last_name', '=', 'Aniston').or('last_name', '=', 'Stallone')
      )
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      where (
      ("first_name" = $1 or "first_name" = $2)
      and
      ("last_name" = $3 or "last_name" = $4)
      )

      You can add expressions conditionally like this:

      import { Expression, SqlBool } from 'kysely'

      const firstName: string | undefined = 'Jennifer'
      const lastName: string | undefined = 'Aniston'
      const under18 = true
      const over60 = true

      let query = db
      .selectFrom('person')
      .selectAll()

      if (firstName) {
      // The query builder is immutable. Remember to reassign
      // the result back to the query variable.
      query = query.where('first_name', '=', firstName)
      }

      if (lastName) {
      query = query.where('last_name', '=', lastName)
      }

      if (under18 || over60) {
      // Conditional OR expressions can be added like this.
      query = query.where((eb) => {
      const ors: Expression<SqlBool>[] = []

      if (under18) {
      ors.push(eb('age', '<', 18))
      }

      if (over60) {
      ors.push(eb('age', '>', 60))
      }

      return eb.or(ors)
      })
      }

      const persons = await query.execute()

      Both the first and third argument can also be arbitrary expressions like subqueries. An expression can defined by passing a function and calling the methods of the ExpressionBuilder passed to the callback:

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where(
      (qb) => qb.selectFrom('pet')
      .select('pet.name')
      .whereRef('pet.owner_id', '=', 'person.id')
      .limit(1),
      '=',
      'Fluffy'
      )
      .execute()

      The generated SQL (PostgreSQL):

      select *
      from "person"
      where (
      select "pet"."name"
      from "pet"
      where "pet"."owner_id" = "person"."id"
      limit $1
      ) = $2

      A where in query can be built by using the in operator and an array of values. The values in the array can also be expressions:

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where('person.id', 'in', [100, 200, 300])
      .execute()

      The generated SQL (PostgreSQL):

      select * from "person" where "id" in ($1, $2, $3)
      

      For complex where expressions you can pass in a single callback and use the ExpressionBuilder to build your expression:

      const firstName = 'Jennifer'
      const maxAge = 60

      const persons = await db
      .selectFrom('person')
      .selectAll('person')
      .where(({ eb, or, and, not, exists, selectFrom }) => and([
      or([
      eb('first_name', '=', firstName),
      eb('age', '<', maxAge)
      ]),
      not(exists(
      selectFrom('pet')
      .select('pet.id')
      .whereRef('pet.owner_id', '=', 'person.id')
      ))
      ]))
      .execute()

      The generated SQL (PostgreSQL):

      select "person".*
      from "person"
      where (
      (
      "first_name" = $1
      or "age" < $2
      )
      and not exists (
      select "pet"."id" from "pet" where "pet"."owner_id" = "person"."id"
      )
      )

      If everything else fails, you can always use the sql tag as any of the arguments, including the operator:

      importsql } from 'kysely'

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where(
      sql<string>`coalesce(first_name, last_name)`,
      'like',
      '%' + name + '%',
      )
      .execute()

      The generated SQL (PostgreSQL):

      select * from "person"
      where coalesce(first_name, last_name) like $1

      In all examples above the columns were known at compile time (except for the raw sql expressions). By default kysely only allows you to refer to columns that exist in the database and can be referred to in the current query and context.

      Sometimes you may want to refer to columns that come from the user input and thus are not available at compile time.

      You have two options, the sql tag or db.dynamic. The example below uses both:

      importsql } from 'kysely'
      const { ref } = db.dynamic

      const columnFromUserInput: string = 'id'

      const persons = await db
      .selectFrom('person')
      .selectAll()
      .where(ref(columnFromUserInput), '=', 1)
      .where(sql.id(columnFromUserInput), '=', 2)
      .execute()

      Type Parameters

      • RE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>
      • VE extends any

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>

    • Type Parameters

      Parameters

      • expression: E

      Returns UpdateQueryBuilder<DB, UT, TB, O>

    • Adds a where clause where both sides of the operator are references to columns.

      The normal where method treats the right hand side argument as a value by default. whereRef treats it as a column reference. This method is expecially useful with joins and correlated subqueries.

      Usage with a join:

      db.selectFrom(['person', 'pet'])
      .selectAll()
      .whereRef('person.first_name', '=', 'pet.name')

      The generated SQL (PostgreSQL):

      select * from "person", "pet" where "person"."first_name" = "pet"."name"
      

      Usage in a subquery:

      const persons = await db
      .selectFrom('person')
      .selectAll('person')
      .select((eb) => eb
      .selectFrom('pet')
      .select('name')
      .whereRef('pet.owner_id', '=', 'person.id')
      .limit(1)
      .as('pet_name')
      )
      .execute()

      The generated SQL (PostgreSQL):

      select "person".*, (
      select "name"
      from "pet"
      where "pet"."owner_id" = "person"."id"
      limit $1
      ) as "pet_name"
      from

      Type Parameters

      • LRE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>
      • RRE extends
            | string
            | Expression<any>
            | DynamicReferenceBuilder<any>
            | SelectQueryBuilderExpression<Record<string, any>>
            | OperandExpressionFactory<DB, TB, any>

      Parameters

      Returns UpdateQueryBuilder<DB, UT, TB, O>