orderBy๋ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํน์ ์ปฌ๋ผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ ๋ฉ์๋์
๋๋ค. ์ค๋ฆ์ฐจ์(ASC) ๋๋ ๋ด๋ฆผ์ฐจ์(DESC)์ผ๋ก ์ ๋ ฌํ ์ ์์ผ๋ฉฐ, ์ฌ๋ฌ ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
์ค๋ฆ์ฐจ์ (ASC)
const users = await puri.table("users")
.select({ id: "users.id", name: "users.name" })
.orderBy("users.name", "asc");
// ORDER BY users.name ASC
๋ด๋ฆผ์ฐจ์ (DESC)
const posts = await puri.table("posts")
.select({ id: "posts.id", title: "posts.title", created_at: "posts.created_at" })
.orderBy("posts.created_at", "desc");
// ORDER BY posts.created_at DESC
์ฌ๋ฌ ์ปฌ๋ผ ์ ๋ ฌ
orderBy๋ฅผ ์ฒด์ด๋ํ์ฌ ์ฌ๋ฌ ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌํ ์ ์์ต๋๋ค.
const users = await puri.table("users")
.select({ id: "users.id", role: "users.role", name: "users.name" })
.orderBy("users.role", "asc") // ์ฒซ ๋ฒ์งธ: role ์ค๋ฆ์ฐจ์
.orderBy("users.name", "asc"); // ๋ ๋ฒ์งธ: name ์ค๋ฆ์ฐจ์
// ORDER BY users.role ASC, users.name ASC
์ ๋ ฌ ์ฐ์ ์์:
- ์ฒซ ๋ฒ์งธ
orderBy - ์ฃผ ์ ๋ ฌ
- ๋ ๋ฒ์งธ
orderBy - ๋ถ ์ ๋ ฌ (์ฃผ ์ ๋ ฌ์ด ๊ฐ์ ๋)
- ์ธ ๋ฒ์งธ
orderBy - ์ผ์ฐจ ์ ๋ ฌ (๋ถ ์ ๋ ฌ๋ ๊ฐ์ ๋)
์ค์ ์์
์ต์ ์
์ํ๋ฒณ์
๋ณตํฉ ์ ๋ ฌ
์ซ์ ์ ๋ ฌ
NULL ์ฒ๋ฆฌ
// ์ต์ ๊ฒ์๋ฌผ ๋จผ์
const posts = await puri.table("posts")
.select({
id: "posts.id",
title: "posts.title",
created_at: "posts.created_at"
})
.orderBy("posts.created_at", "desc")
.limit(20);
// ๊ฐ์ฅ ์ต๊ทผ์ ์
๋ฐ์ดํธ๋ ๊ฒ ๋จผ์
const users = await puri.table("users")
.select({
id: "users.id",
name: "users.name",
updated_at: "users.updated_at"
})
.orderBy("users.updated_at", "desc");
// ์ด๋ฆ ๊ฐ๋๋ค์
const users = await puri.table("users")
.select({
id: "users.id",
name: "users.name"
})
.orderBy("users.name", "asc");
// ์ ๋ชฉ ์ํ๋ฒณ ์ญ์
const products = await puri.table("products")
.select({
id: "products.id",
name: "products.name"
})
.orderBy("products.name", "desc");
// ์ฐ์ ์์: ์ํ โ ์์ฑ์ผ
const orders = await puri.table("orders")
.select({
id: "orders.id",
status: "orders.status",
created_at: "orders.created_at"
})
.orderBy("orders.status", "asc") // pending โ processing โ completed
.orderBy("orders.created_at", "desc"); // ์ต์ ์
// ์ฐ์ ์์: featured โ ํ์ โ ํ๋งค๋
const products = await puri.table("products")
.select({
id: "products.id",
name: "products.name",
featured: "products.featured",
rating: "products.rating",
sales: "products.sales"
})
.orderBy("products.featured", "desc") // ์ถ์ฒ ์ํ ๋จผ์
.orderBy("products.rating", "desc") // ๋์ ํ์
.orderBy("products.sales", "desc"); // ๋ง์ด ํ๋ฆฐ ๊ฒ
// ๊ฐ๊ฒฉ ๋ฎ์ ์
const products = await puri.table("products")
.select({
id: "products.id",
name: "products.name",
price: "products.price"
})
.where("products.published", true)
.orderBy("products.price", "asc");
// ์กฐํ์ ๋์ ์
const posts = await puri.table("posts")
.select({
id: "posts.id",
title: "posts.title",
views: "posts.views"
})
.orderBy("posts.views", "desc")
.limit(10);
// NULL์ ๋ง์ง๋ง์ผ๋ก
const users = await puri.table("users")
.select({
id: "users.id",
name: "users.name",
last_login: "users.last_login"
})
.orderBy("users.last_login", "desc"); // NULL์ ์๋์ผ๋ก ๋ง์ง๋ง
// NULL์ ๋จผ์
const posts = await puri.table("posts")
.select({
id: "posts.id",
title: "posts.title",
deleted_at: "posts.deleted_at"
})
.orderBy("posts.deleted_at", "asc"); // NULL์ด ๋จผ์ ์ด
์กฐ์ธ๋ ํ
์ด๋ธ ์ ๋ ฌ
์กฐ์ธํ ํ
์ด๋ธ์ ์ปฌ๋ผ์ผ๋ก๋ ์ ๋ ฌํ ์ ์์ต๋๋ค.
const posts = await puri.table("posts")
.join("users", "posts.user_id", "users.id")
.select({
post_id: "posts.id",
title: "posts.title",
author_name: "users.name"
})
.orderBy("users.name", "asc") // ์์ฑ์ ์ด๋ฆ์
.orderBy("posts.created_at", "desc"); // ๊ฐ์ ์์ฑ์๋ ์ต์ ์
// ORDER BY users.name ASC, posts.created_at DESC
SELECT ๋ณ์นญ์ผ๋ก ์ ๋ ฌ
SELECT์์ ์ง์ ํ ๋ณ์นญ์ผ๋ก๋ ์ ๋ ฌํ ์ ์์ต๋๋ค.
const posts = await puri.table("posts")
.select({
id: "posts.id",
title: "posts.title",
view_count: "posts.views" // ๋ณ์นญ ์ง์
})
.orderBy("view_count", "desc"); // ๋ณ์นญ ์ฌ์ฉ
// SELECT posts.views as view_count
// ORDER BY view_count DESC
์ง๊ณ ํจ์ ์ ๋ ฌ
GROUP BY์ ํจ๊ป ์ง๊ณ ํจ์ ๊ฒฐ๊ณผ๋ก ์ ๋ ฌํ ์ ์์ต๋๋ค.
const userStats = await puri.table("posts")
.select({
user_id: "posts.user_id",
post_count: Puri.count()
})
.groupBy("posts.user_id")
.orderBy("post_count", "desc") // ๊ฒ์๋ฌผ ๋ง์ ์
.limit(10);
// SELECT user_id, COUNT(*) as post_count
// FROM posts
// GROUP BY user_id
// ORDER BY post_count DESC
// LIMIT 10
์ ๋ ฌ ๋ฐฉํฅ
ASC (์ค๋ฆ์ฐจ์)
- ์ซ์: ์์ ๊ฐ โ ํฐ ๊ฐ
- ๋ฌธ์: A โ Z, ๊ฐ โ ํ
- ๋ ์ง: ๊ณผ๊ฑฐ โ ๋ฏธ๋
- NULL: ๋ง์ง๋ง
.orderBy("users.age", "asc")
// 18, 25, 30, 35, 40, NULL
DESC (๋ด๋ฆผ์ฐจ์)
- ์ซ์: ํฐ ๊ฐ โ ์์ ๊ฐ
- ๋ฌธ์: Z โ A, ํ โ ๊ฐ
- ๋ ์ง: ๋ฏธ๋ โ ๊ณผ๊ฑฐ
- NULL: ๋ง์ง๋ง
.orderBy("users.age", "desc")
// 40, 35, 30, 25, 18, NULL
๊ธฐ๋ณธ๊ฐ์ ASC์
๋๋ค. ๋ฐฉํฅ์ ์ง์ ํ์ง ์์ผ๋ฉด ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋ฉ๋๋ค.
์ฑ๋ฅ ์ต์ ํ
1. ์ธ๋ฑ์ค ํ์ฉ
// โ
์ข์: ์ธ๋ฑ์ค ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌ
.orderBy("users.created_at", "desc") // created_at์ ์ธ๋ฑ์ค ํ์
// โ ๋์จ: ์ธ๋ฑ์ค ์๋ ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌ (๋๋ฆผ)
.orderBy("users.bio", "asc")
๊ถ์ฅ ์ธ๋ฑ์ค:
CREATE INDEX idx_users_created_at ON users(created_at DESC);
CREATE INDEX idx_posts_published_created ON posts(published, created_at DESC);
2. LIMIT๊ณผ ํจ๊ป ์ฌ์ฉ
// โ
์ข์: ์์ N๊ฐ๋ง ์ ๋ ฌ
.orderBy("posts.views", "desc")
.limit(10) // ์ ์ฒด๋ฅผ ์ ๋ ฌํ์ง ์๊ณ ์์ 10๊ฐ๋ง
// โ ๏ธ ์ฃผ์: LIMIT ์์ผ๋ฉด ๋ชจ๋ ํ ์ ๋ ฌ (๋๋ฆผ)
.orderBy("posts.views", "desc")
3. ๋ณตํฉ ์ธ๋ฑ์ค
์ฌ๋ฌ ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌํ ๋๋ ๋ณตํฉ ์ธ๋ฑ์ค๊ฐ ํ์ํฉ๋๋ค.
// ์ด ์ฟผ๋ฆฌ์๋
.orderBy("products.category", "asc")
.orderBy("products.price", "asc")
// ์ด๋ฐ ์ธ๋ฑ์ค๊ฐ ํ์
CREATE INDEX idx_products_category_price ON products(category, price);
์ฃผ์์ฌํญ
1. ์ ๋ ฌ ์์
// orderBy ์์๊ฐ ์ค์ํจ
// โ
์ฌ๋ฐ๋ฆ: ์ํ โ ๋ ์ง
.orderBy("orders.status", "asc")
.orderBy("orders.created_at", "desc")
// โ ์๋์ ๋ค๋ฆ: ๋ ์ง โ ์ํ
.orderBy("orders.created_at", "desc")
.orderBy("orders.status", "asc")
2. NULL ๊ฐ
// PostgreSQL๊ณผ MySQL์ NULL ์ ๋ ฌ์ด ๋ค๋ฅผ ์ ์์
// PostgreSQL: NULL LAST (๊ธฐ๋ณธ)
.orderBy("users.last_login", "desc")
// ๋ช
์์ ์ผ๋ก ์ง์ ํ๋ ค๋ฉด raw SQL
.whereRaw("ORDER BY users.last_login DESC NULLS FIRST")
3. ๋์๋ฌธ์ ๊ตฌ๋ถ
// โ ๏ธ ์ฃผ์: ๋์๋ฌธ์ ๊ตฌ๋ถ ์ ๋ ฌ
.orderBy("users.name", "asc")
// "Alice", "Bob", "alice", "bob"
// ๋์๋ฌธ์ ๋ฌด์ํ๋ ค๋ฉด
.orderBy(puri.raw("LOWER(users.name)"), "asc")
// "Alice", "alice", "Bob", "bob"
4. ์ฑ๋ฅ ์ํฅ
// โ ๋์จ: ๋์ฉ๋ ๋ฐ์ดํฐ ์ ์ฒด ์ ๋ ฌ
const allUsers = await puri.table("users")
.orderBy("users.created_at", "desc"); // ์๋ฐฑ๋ง ํ ์ ๋ ฌ
// โ
์ข์: LIMIT์ผ๋ก ์ ํ
const recentUsers = await puri.table("users")
.orderBy("users.created_at", "desc")
.limit(100); // ์์ 100๊ฐ๋ง
ํ์
์์ ์ฑ
orderBy๋ ํ์
์์ ํ๊ฒ ์ปฌ๋ผ์ ๊ฒ์ฆํฉ๋๋ค.
// โ
์ฌ๋ฐ๋ฅธ ์ปฌ๋ผ
await puri.table("users")
.orderBy("users.created_at", "desc");
// โ ํ์
์๋ฌ: ์กด์ฌํ์ง ์๋ ์ปฌ๋ผ
await puri.table("users")
.orderBy("users.unknown_field", "desc");
// โ ํ์
์๋ฌ: ์๋ชป๋ ๋ฐฉํฅ
await puri.table("users")
.orderBy("users.name", "invalid"); // "asc" ๋๋ "desc"๋ง ๊ฐ๋ฅ
๋ค์ ๋จ๊ณ