> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chainstream.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 정렬 및 페이지네이션

> orderBy 입력 객체로 쿼리 결과를 정렬하고 limit으로 페이지네이션 — 명명 규칙, 기본값, offset 기반 페이지네이션

## orderBy InputObject

각 Cube는 `ascending` 과 `descending` 필드를 가진 `{Cube}OrderBy` 입력 객체를 생성합니다. 각 필드는 차원 경로를 밑줄로 이은 `CompareFields` enum 값을 받습니다:

```
{DimensionGroup}_{DimensionField}
```

중첩 차원은 레벨마다 이어 붙입니다:

```
Block_Time
Trade_Buy_Amount
Trade_Buy_PriceInUSD
```

사용 예:

```graphql theme={null}
orderBy: {descending: Block_Time}      # newest first
orderBy: {ascending: Trade_Buy_Amount}  # smallest amount first
```

### 자주 쓰는 CompareFields 값

<div style={{ overflowX: 'auto', width: '100%' }}>
  | CompareFields 값        | 사용 예                                          | Cube                                                                              | 설명              |
  | :--------------------- | :-------------------------------------------- | :-------------------------------------------------------------------------------- | :-------------- |
  | `Block_Time`           | `orderBy: {descending: Block_Time}`           | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | 최신순             |
  | `Block_Time`           | `orderBy: {ascending: Block_Time}`            | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | 오래된 순           |
  | `Interval_Time_Start`  | `orderBy: {ascending: Interval_Time_Start}`   | Pairs, Tokens                                                                     | 오래된 순(구간 시작 시각) |
  | `Trade_Buy_Amount`     | `orderBy: {descending: Trade_Buy_Amount}`     | DEXTrades                                                                         | 매수 금액 큰 순       |
  | `Trade_Buy_PriceInUSD` | `orderBy: {descending: Trade_Buy_PriceInUSD}` | DEXTrades                                                                         | USD 가격 높은 순     |
  | `Transfer_AmountInUSD` | `orderBy: {descending: Transfer_AmountInUSD}` | Transfers                                                                         | USD 전송액 큰 순     |
  | `LatestBalanceUSD`     | `orderBy: {descending: LatestBalanceUSD}`     | TokenHolders                                                                      | 보유액 큰 순         |
  | `BuyVolumeUSDState`    | `orderBy: {descending: BuyVolumeUSDState}`    | WalletTokenPnL                                                                    | 매수 볼륨 큰 순       |
</div>

<Tip>
  [GraphQL IDE](https://ide.chainstream.io) 자동완성으로 Cube별 사용 가능한 모든 `CompareFields` 값을 확인하세요 — `orderBy: {descending:` 까지 입력하면 IDE가 필드를 보여 줍니다.
</Tip>

### 사용법

`descending` 또는 `ascending` 중 하나에 `CompareFields` 값을 넣은 `orderBy` 입력 객체를 전달합니다:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade { Buy { Amount PriceInUSD } }
    }
  }
}
```

<Note>
  `orderBy` 는 **한 쌍**(방향·필드)만 받습니다. 다중 컬럼 정렬은 지원되지 않으며, 한 번에 하나의 차원으로만 정렬됩니다.
</Note>

***

## limit 인자

`limit` 인자는 반환 행 수를 제어하며 offset 기반 페이지네이션을 지원합니다:

```graphql theme={null}
input LimitInput {
  count: Int   # Number of rows to return
  offset: Int  # Number of rows to skip
}
```

### 기본값과 최대값

각 Cube에는 `limit` 를 생략할 때 적용되는 **기본** limit와 **최대** 상한이 있습니다:

| Cube               | 기본 `count` | 최대 `count` |
| :----------------- | :--------- | :--------- |
| DEXTrades          | 25         | 10,000     |
| Transfers          | 25         | 10,000     |
| BalanceUpdates     | 25         | 10,000     |
| DEXPools           | 25         | 10,000     |
| TokenSupplyUpdates | 25         | 10,000     |
| Pairs              | 25         | 10,000     |
| Tokens             | 25         | 10,000     |
| DEXPoolEvents      | 25         | 10,000     |
| TokenHolders       | 25         | 10,000     |
| WalletTokenPnL     | 25         | 10,000     |

<Info>
  요청한 `count` 가 최대를 넘으면 서버는 조용히 최대값으로 잘라 냅니다.
</Info>

***

## Offset 기반 페이지네이션

`offset` 으로 결과 집합을 페이지 넘깁니다. 패턴은 단순합니다:

* **1페이지**: `limit: { count: 50, offset: 0 }`
* **2페이지**: `limit: { count: 50, offset: 50 }`
* **3페이지**: `limit: { count: 50, offset: 100 }`

### 예: 토큰 홀더 페이지네이션

<Tabs>
  <Tab title="1페이지">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 0 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>

  <Tab title="2페이지">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 20 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>
</Tabs>

### 페이지네이션 팁

<AccordionGroup>
  <Accordion title="페이지네이션에는 항상 orderBy 사용">
    정렬 순서가 고정되지 않으면 페이지 사이에서 행이 밀릴 수 있습니다. `limit` 은 결정적 순서를 만드는 `orderBy` 와 함께 쓰세요.
  </Accordion>

  <Accordion title="깊은 offset 피하기">
    `offset` 이 매우 크면(예: 50,000+) DB가 행을 스캔·건너뛰어야 해 성능이 나빠질 수 있습니다. 매우 큰 데이터셋에서는 깊게 페이지 넘기기보다 `where` 로 쿼리를 좁히세요.
  </Accordion>

  <Accordion title="끝 판별에 행 개수 사용">
    한 페이지에서 요청한 `count` 보다 적은 행이 오면 데이터 끝에 도달한 것입니다. 또는 미리 `count` 메트릭 필드로 전체 행 수를 구할 수 있습니다.
  </Accordion>
</AccordionGroup>

***

## 실전 예시

### 최근 대형 거래

Solana에서 매수 가치가 \$10,000를 넘는 가장 최근 DEX 거래 10건:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      where: {
        Trade: { Buy: { PriceInUSD: { gt: 10000 } } }
      }
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade {
        Buy {
          Currency { MintAddress }
          Amount
          PriceInUSD
        }
        Dex { ProtocolName }
      }
    }
  }
}
```

### OHLC 캔들 — 최근 60분

토큰의 1분봉을 시간순으로 가져오기:

```graphql theme={null}
query {
  Trading {
    Pairs(
      where: {
        Token: { Address: { is: "So11111111111111111111111111111111111111112" } }
        Market: { Network: { is: "sol" } }
        Block: { Time: { after: "2025-03-27T09:00:00Z" } }
      }
      orderBy: {ascending: Block_Time}
      limit: { count: 60 }
    ) {
      Block { Time }
      Price {
        Ohlc { Open High Low Close }
      }
      Volume { Usd }
      Stats { TradeCount }
    }
  }
}
```

### 상위 50 토큰 홀더

USD 잔액 기준 상위 50명 홀더:

```graphql theme={null}
query {
  Solana {
    TokenHolders(
      tokenAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
      orderBy: {descending: LatestBalanceUSD}
      limit: { count: 50 }
    ) {
      Holder { Address }
      LatestBalance
      LatestBalanceUSD
      FirstSeen
      LastSeen
    }
  }
}
```

***

## 다음 단계

<CardGroup cols={2}>
  <Card title="필터링" icon="filter" href="/ko/graphql/schema/filtering">
    정렬과 필터를 조합해 정밀한 분석 쿼리를 만듭니다.
  </Card>

  <Card title="메트릭 및 집계" icon="chart-simple" href="/ko/graphql/schema/metrics-aggregation">
    count, sum, avg, min, max, uniq 로 정렬된 데이터를 집계합니다.
  </Card>
</CardGroup>
