Drizzle | 计算行数
PostgreSQL
MySQL
SQLite
本指南假定您熟悉

要计算表中的所有行,您可以使用 count() 函数或 sql 操作符,如下所示

index.ts
schema.ts
import { count, sql } from 'drizzle-orm';
import { products } from './schema';

const db = drizzle(...);

await db.select({ count: count() }).from(products);

// Under the hood, the count() function casts its result to a number at runtime.
await db.select({ count: sql`count(*)`.mapWith(Number) }).from(products);
// result type
type Result = {
  count: number;
}[];
select count(*) from products;

要计算指定列中包含非 NULL 值的行,您可以使用带有列参数的 count() 函数

await db.select({ count: count(products.discount) }).from(products);
// result type
type Result = {
  count: number;
}[];
select count("discount") from products;

Drizzle 拥有简单灵活的 API,可让您创建自定义解决方案。在 PostgreSQL 和 MySQL 中,count() 函数返回 bigint 类型,其驱动程序会将其解释为字符串,因此应将其转换为整数

import { AnyColumn, sql } from 'drizzle-orm';

const customCount = (column?: AnyColumn) => {
  if (column) {
    return sql<number>`cast(count(${column}) as integer)`; // In MySQL cast to unsigned integer
  } else {
    return sql<number>`cast(count(*) as integer)`; // In MySQL cast to unsigned integer
  }
};

await db.select({ count: customCount() }).from(products);
await db.select({ count: customCount(products.discount) }).from(products);
select cast(count(*) as integer) from products;
select cast(count("discount") as integer) from products;

在 SQLite 中,count() 结果返回为整数。

import { sql } from 'drizzle-orm';

await db.select({ count: sql<number>`count(*)` }).from(products);
await db.select({ count: sql<number>`count(${products.discount})` }).from(products);
select count(*) from products;
select count("discount") from products;
重要提示

通过指定 sql<number>,您是在告诉 Drizzle 该字段的预期类型是 number
如果您错误地指定(例如,对将返回数字的字段使用 sql<string>),则运行时值将与预期类型不匹配。Drizzle 无法根据提供的泛型类型执行任何类型转换,因为该信息在运行时不可用。

如果您需要对返回值应用运行时转换,可以使用 .mapWith() 方法。

要计算符合条件的行,您可以使用 .where() 方法

import { count, gt } from 'drizzle-orm';

await db
  .select({ count: count() })
  .from(products)
  .where(gt(products.price, 100));
select count(*) from products where price > 100

您可以这样将 count() 函数与联接和聚合一起使用

index.ts
schema.ts
import { count, eq } from 'drizzle-orm';
import { countries, cities } from './schema';

// Count cities in each country
await db
  .select({
    country: countries.name,
    citiesCount: count(cities.id),
  })
  .from(countries)
  .leftJoin(cities, eq(countries.id, cities.countryId))
  .groupBy(countries.id)
  .orderBy(countries.name);
select countries.name, count("cities"."id") from countries
  left join cities on countries.id = cities.country_id
  group by countries.id
  order by countries.name;