Belajar Drizzle ORM - Advanced Select: Filtering, Sorting & Pagination
Episode 6 of 21

Belajar Drizzle ORM - Advanced Select: Filtering, Sorting & Pagination

Operators filtering (eq, ne, gt, lt, gte, lte, and, or, not, inArray, like, ilike), sorting dengan desc/asc, aggregations (count, sum, avg), group by & having, serta SQL template literals untuk raw SQL yang aman dari SQL injection.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 5 kita mempelajari operasi CRUD dasar — insert, select, update, delete — pada episode ini kita masuk ke advanced select: filtering dengan berbagai operators, sorting, aggregations, group by, dan SQL template literals untuk raw SQL yang aman.

Query yang kompleks membutuhkan filtering yang tepat, sorting yang benar, dan aggregations untuk analisis data. Drizzle ORM menyediakan semua ini dengan API yang mirip SQL.

Advanced Filtering

Comparison Operators

Comparison operators
import { eq, ne, gt, lt, gte, lte } from 'drizzle-orm'
 
// eq: sama dengan
await db.select().from(users).where(eq(users.age, 25))
 
// ne: tidak sama dengan
await db.select().from(users).where(ne(users.role, 'guest'))
 
// gt, lt, gte, lte: greater than, less than, greater/less or equal
await db.select().from(users).where(gt(users.age, 18))
await db.select().from(users).where(lte(users.age, 65))

Logical Operators

Logical operators
import { and, or, not } from 'drizzle-orm'
 
// AND
await db.select().from(users).where(
  and(eq(users.isActive, true), gt(users.age, 18))
)
 
// OR
await db.select().from(users).where(
  or(eq(users.role, 'admin'), eq(users.role, 'moderator'))
)
 
// NOT
await db.select().from(users).where(not(eq(users.isActive, false)))

Array Operators

IN dan LIKE operators
import { inArray, notInArray, like, ilike } from 'drizzle-orm'
 
// IN
await db.select().from(users).where(
  inArray(users.role, ['admin', 'moderator'])
)
 
// LIKE (case-sensitive)
await db.select().from(users).where(like(users.name, '%John%'))
 
// ILIKE (case-insensitive)
await db.select().from(users).where(ilike(users.name, '%john%'))

Sorting

Sorting dengan desc dan asc
import { desc, asc } from 'drizzle-orm'
 
// Sort by newest first
await db.select().from(users).orderBy(desc(users.createdAt))
 
// Sort by name alphabetically
await db.select().from(users).orderBy(asc(users.name))
 
// Multiple sort criteria
await db.select().from(posts)
  .orderBy(desc(posts.publishedAt), asc(posts.title))

Pagination

Pagination dengan limit dan offset
// Page 1: 10 items pertama
await db.select().from(users).limit(10).offset(0)
 
// Page 2: 10 items berikutnya
await db.select().from(users).limit(10).offset(10)
 
// Page 3: 10 items berikutnya
await db.select().from(users).limit(10).offset(20)

Aggregations

Aggregations: count, sum, avg
import { count, sum, avg } from 'drizzle-orm'
 
// Count semua users
const [total] = await db.select({ total: count() }).from(users)
 
// Count active users
const [activeCount] = await db.select({ total: count() })
  .from(users)
  .where(eq(users.isActive, true))
 
// Sum dan avg
const [stats] = await db.select({
  totalAge: sum(users.age),
  avgAge: avg(users.age),
}).from(users)

Group By & Having

Group By dengan Having clause
// Group by role, count per role
await db.select({
  role: users.role,
  total: count(),
}).from(users).groupBy(users.role)
 
// Group by dengan having: role dengan lebih dari 5 users
await db.select({
  role: users.role,
  total: count(),
}).from(users)
  .groupBy(users.role)
  .having(gte(count(), 5))

SQL Template Literals

Untuk query yang sulit di-express dengan query builder:

Raw SQL dengan template literals (aman dari SQL injection)
import { sql } from 'drizzle-orm'
 
// Raw SQL dengan parameter
const result = await db.execute(
  sql`SELECT * FROM users WHERE age > ${25}`
)
 
// Komposisi query
const conditions = sql`${users.age} > ${18}`
const result = await db.select().from(users).where(
  sql`${conditions} AND ${users.isActive} = true`
)

Warning

Hindari raw SQL jika bisa di-express dengan query builder. Template literals Drizzle aman dari SQL injection karena menggunakan parameterized queries, tetapi query builder memberikan type safety yang lebih baik.

Penutup

Pada episode 6 ini, kalian telah memahami Advanced Select:

  • Filtering: eq, ne, gt, lt, and, or, not, inArray, like, ilike.
  • Sorting: desc() dan asc() untuk satu atau beberapa kolom.
  • Pagination: limit() dan offset().
  • Aggregations: count(), sum(), avg().
  • Group By & Having: groupBy() dengan having() untuk filtering aggregate.
  • SQL template literals: raw SQL aman dari SQL injection.

Di episode 7 selanjutnya kita akan mempelajari Relational Queries & Relations Definition — mendefinisikan relasi antar tabel (one-to-many, many-to-one) dan melakukan nested queries. Sampai jumpa di episode 7!

Belajar Drizzle ORM - Advanced Select: Filtering, Sorting & Pagination | Belajar Drizzle ORM