# 排序與分頁

本頁說明 `orderBy()`、`limit()`、`offset()` 與 `total()` 如何組合出分頁查詢。

## `orderBy()`

```typescript
MySQLPool.table("users").orderBy("created_at", "DESC").orderBy("id");
// ... ORDER BY `created_at` DESC, `id` ASC
```

| 規則 | 說明 |
|---|---|
| 預設方向 | `ASC` |
| 大小寫 | 方向先轉成大寫，`"desc"` 與 `"DESC"` 相同 |
| 欄位名 | 不含 `.` 時加反引號 |
| 多次呼叫 | 依呼叫順序以逗號串接 |

## `limit()` 與 `offset()`

```typescript
const page = 3;
const perPage = 20;

MySQLPool
  .table("users")
  .limit(perPage)
  .offset((page - 1) * perPage);
// ... LIMIT 20 OFFSET 40
```

## `total()`

`total()` 把原查詢包成子查詢，以 `COUNT(*) OVER()` 讓每一列都帶上符合條件的總筆數（`src/MySQLPool.ts:254-256`），分頁時不必再發一次 `COUNT(*)`。

```typescript
interface UserRow {
  total: number;
  id: number;
  name: string;
}

const rows = await MySQLPool
  .table("users")
  .select("id", "name")
  .where("status", "active")
  .total()
  .orderBy("id", "DESC")
  .limit(10)
  .offset(0)
  .get<UserRow>();

const total = rows[0]?.total ?? 0;
```

產生的 SQL：

```sql
SELECT COUNT(*) OVER() AS total, data.*
FROM (SELECT `id`, `name` FROM `users` WHERE `status` = ?) AS data
ORDER BY `id` DESC LIMIT 10 OFFSET 0
```

## 相關頁面

- [欄位與條件](/zh/select-and-where)
- [建構器狀態](/zh/builder-state)
