Drizzle | 행 개수 세기
This guide assumes familiarity with:
테이블의 모든 행 개수를 세려면 count()
함수나 sql
연산자를 사용할 수 있습니다.
import { count , sql } from 'drizzle-orm' ;
import { products } from './schema' ;
const db = drizzle ( ... );
await db .select ({ count : count () }) .from (products);
// count() 함수는 런타임에 결과를 숫자로 변환합니다.
await db .select ({ count : sql `count(*)` .mapWith (Number) }) .from (products);
// 결과 타입
type Result = {
count : number ;
}[];
select count ( * ) from products;
import { integer , pgTable , serial , text } from 'drizzle-orm/pg-core' ;
export const products = pgTable ( 'products' , {
id : serial ( 'id' ) .primaryKey () ,
name : text ( 'name' ) .notNull () ,
discount : integer ( 'discount' ) ,
price : integer ( 'price' ) .notNull () ,
});
특정 컬럼에 NULL이 아닌 값이 있는 행의 개수를 세려면 count()
함수에 컬럼을 지정하면 됩니다.
await db .select ({ count : count ( products .discount) }) .from (products);
// 결과 타입
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 `cast(count( ${ column } ) as integer)` ; // MySQL에서는 unsigned integer로 변환
} else {
return sql `cast(count(*) as integer)` ; // MySQL에서는 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 `count(*)` }) .from (products);
await db .select ({ count : sql `count( ${ products .discount } )` }) .from (products);
select count ( * ) from products;
select count ( "discount" ) from products;
IMPORTANT
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()
함수를 사용하는 방법은 다음과 같습니다.
import { count , eq } from 'drizzle-orm' ;
import { countries , cities } from './schema' ;
// 각 나라의 도시 개수 세기
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;
import { integer , pgTable , serial , text } from 'drizzle-orm/pg-core' ;
export const countries = pgTable ( 'countries' , {
id : serial ( 'id' ) .primaryKey () ,
name : text ( 'name' ) .notNull () ,
});
export const cities = pgTable ( 'cities' , {
id : serial ( 'id' ) .primaryKey () ,
name : text ( 'name' ) .notNull () ,
countryId : integer ( 'country_id' ) .notNull () .references (() => countries .id) ,
});