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

> 組み込み Web SQL UI（`/play`）でクエリ結果をソート、フィルタリング、ページングするためのドキュメント

# Web UI のソート、フィルタリング、ページネーション

組み込み Web SQL UI (任意の ClickHouse HTTP ポートの [`/play`](/docs/ja/concepts/features/interfaces/http) パスで提供される `play.html`) では、クエリを編集せずに、結果をカラムでソートし、その値でフィルタリングし、ページ単位で表示できます。

これらの処理はどれもブラウザ内では行われません。変更するたびに、対応するクエリ構築設定を使用してクエリが再実行され、サーバーはクエリを外側の `ORDER BY`、`WHERE`、`LIMIT` を持つ派生テーブルとしてラップすることで、その設定をマテリアライズします。したがって、画面に表示される結果は、ページにたまたま含まれていた行を並べ替えたものではなく、クエリ全体をソート、フィルタリング、ページングした結果です。

<div id="sorting">
  ## ソート
</div>

各カラムヘッダーの右側には 2 つの矢印が表示されます。▲ はそのカラムで結果を昇順にソートし、▼ は降順にソートします。矢印をクリックするとそのソートが有効になり、クエリが再実行されます。すでに有効な方向の矢印をクリックするとソートが解除され、反対方向の矢印をクリックするとその方向に切り替わります。矢印は実際のボタンであるため、キーボード利用者は Tab キーでフォーカスを移動し、キーボードで操作できます。また、各矢印はその状態を支援技術に公開します (ヘッダー自体には `aria-sort` が設定されます) 。

ホバー可能なポインター (マウス) を使用するデバイスでは、矢印はヘッダーにホバーしている間、または矢印にフォーカスがある間のみ表示されるため、それ以外では邪魔になりません。ホバー機能のないタッチデバイスやその他の粗いポインターデバイスでは、直接タップできるよう常に表示されます。ソート対象のカラムでは、ホバーしなくても両方の矢印が表示されます。一方はソート状態をひと目で確認できるようにするためであり、もう一方は方向を反転する操作が次に行われる可能性が最も高いためです。

カラムヘッダー内のすべてのアイコンは、制御する機能にかかわらず同じように表示されます。その機能がカラムに適用されていない間は控えめに表示され、適用されると、有効な操作に使用される色、ライトテーマではマゼンタ、ダークテーマでは黄色で表示されます。このとき、ホバーしなくても表示されたままになります。控えめな表示は透明度を下げるのではなく色を抑えることで実現されるため、アイコンがカラム名やセルのカラーコーディングの上で薄く見えることはありません。

<div id="sorting-by-several-columns">
  ### 複数カラムでのソート
</div>

ソートを有効にすると、現在のソートは置き換えられます。以前にソート対象だったカラムは無効になり、クリックしたカラムが唯一のソートキーになります。すでに有効なソートキーを維持したまま、このカラムをその後に追加するには、<kbd>Shift</kbd> を押しながらクリックします。この順序は `ORDER BY` で使用されます。最初のキーで順序が決まり、後続の各キーが前のキーで同順位となった値の順序を決定します。ソートキーが複数ある場合は、各有効な矢印に、その順序におけるカラムの位置も上付き文字で表示されます (▼¹、▲²、…) 。

すでにソートキーになっているカラムで <kbd>Shift</kbd> を使用すると、方向だけが変更され、順序内の位置は維持されます。カラムを無効にすると、そのカラムだけが削除され、残りのキーはそのまま維持されます。

<div id="filtering">
  ## フィルタリング
</div>

<div id="filtering-from-a-column-header">
  ### カラムヘッダーから
</div>

すべてのカラムヘッダーには、ソート矢印の横にファネルアイコンがあり、ソート矢印と同じ操作で表示できます。これをクリックすると、そのカラムに対する述語を入力する欄が開き、右端には適用ボタン (▶) が表示されます。プレースホルダーには、そのカラムの型に応じた述語の書式が示されます。数値なら `> 10`、文字列なら `LIKE '%test%'` です。入力欄はヘッダーセル内に開き、スペースを確保するためにセルは2行分の高さに広がります。この行は、フィルターの設定後にフィルター自体が表示される行と同じため、フィルターは表示される場所で編集できます。入力するのはカラム名に続く部分なので、`> 10` は `WHERE column > 10` となります。この位置でサーバーが受け付ける任意の式を使用できます。たとえば、`BETWEEN 1 AND 5`、`IN (1, 2, 3)`、`IS NOT NULL`、`% 2 = 0` です。

適用ボタン (または <kbd>Enter</kbd>) を押すとフィルターが適用され、クエリが再実行されます。<kbd>Esc</kbd> を押すか、他の場所をクリックまたはTabキーで移動すると、編集は破棄され、入力欄が閉じます。適用する内容がない場合、つまりフィルターが設定されていないカラムの入力欄が空の場合は、適用ボタンは無効になります。ただし、すでにフィルターが設定されているカラムでは、入力欄を空にして適用するとフィルターを削除できるため、入力欄が空でも適用ボタンは有効のままです。複数のカラムのフィルターは `AND` で結合されます。

<div id="filtering-from-a-cell">
  ### セルから
</div>

セルを選択すると、その値でのフィルタリングをカラムがサポートしている場合、コピーアイコンの横にファネルアイコンも表示されます。クリックすると、使用可能な比較方法が表示されます。

| 値                                                    | 使用可能な条件                                                          |
| ---------------------------------------------------- | ---------------------------------------------------------------- |
| 数値                                                   | `=`, `!=`, `>`, `<`, `>=`, `<=`                                  |
| 日付または時刻 (`Date`, `Date32`, `DateTime`, `DateTime64`) | `=`, `!=`, `>`, `<`, `>=`, `<=`                                  |
| 100 文字以下の文字列                                         | `=`, `!=`, `contains` — 空文字列はすべての文字列に含まれるため、`=` と `!=` のみが使用できます |
| `Bool`                                               | `true`, `false` — このセルの値との比較ではなく、値自体を指定します                       |
| `Enum`                                               | `=`, `!=` — 名前の有限集合に対する部分一致は有用なフィルターではありません                      |
| `NULL`                                               | `IS NULL`, `IS NOT NULL`                                         |

いずれかを選択すると、すぐに適用されます。日付、時刻、または列挙型は、サーバーが表示したテキストそのものと比較され、ClickHouse がそれをカラム固有の型として再度パースします (列挙型の場合は値の名前) 。`contains` は、値に含まれる `%` と `_` をエスケープした `LIKE` パターンになるため、値そのものに一致します。上記のいずれにも該当しない値 (配列、タプル、マップ、長いテキスト) のセルにはメニューは表示されません。そのカラムは引き続きヘッダー入力からフィルタリングできます。

<div id="the-filter-in-effect">
  ### 適用中のフィルター
</div>

フィルターが設定されているカラムでは、設定されている間、その名前の下に述語が表示されます。そのため、画面上の行が結果の部分集合であることが常にわかります。ファネルはその横、ヘッダーの左下隅に移動します。述語をクリックすると、その場で入力欄が再び開きます。横にある ✕ をクリックするか、空の入力を適用すると、フィルターが削除されます。どちらの場合もクエリが再実行されます。

フィルターの設定元にかかわらず、カラムごとに設定できるフィルターは 1 つです。セルからフィルターを設定すると、ヘッダーの入力欄で設定されていたフィルターは置き換えられ、ヘッダーには常に適用中のフィルターが表示されます。

フィルター適用後の結果が空の場合でも、カラムヘッダーは保持されます (通常、空の結果には垂直レイアウトが表示されます) 。これにより、一致する項目がなかったフィルターを確認して解除できます。

<div id="pagination">
  ## ページネーション
</div>

結果は上限まで表示されます。上限は1,000行ですが、結果が非常に横長の場合はこれより少なくなります。結果がこの上限で切り詰められ、続きのデータがある場合は、テーブルの下にページャーが表示されます。

```text theme={null}
Page: 1 2 …   Per page: 1000
```

ページ番号をクリックすると、表示上限とそのページ番号が[`page`](/docs/ja/reference/settings/session-settings/other#page)設定として設定され、クエリが再実行されます。サーバーはページ番号を対応する`OFFSET`に変換します。その後、各ページがちょうど埋まり、切り詰められているように見えなくなっても、結果がページ分割されている限りページャーは表示され続けます。

ページ数は不明なため表示されません。結果の行数を数えるには、2回目のクエリを実行する必要があります。ページャーには、現在のページの前の10ページ、現在のページ、次のページが表示され、その後に`…`が続きます。`…`をクリックすると任意のページ番号を入力できるフィールドに変わり、入力欄からフォーカスが外れるとそのページ番号が適用されます (<kbd>Enter</kbd>を押すとフォーカスが外れます) 。

次のページが表示されるのは、現在のページが埋まっている場合のみです。収容可能な行数より少ない行数で返されたページは結果の末尾であるため、その後のページはありません。 (結果の長さがたまたまページサイズのちょうど倍数であっても、さらに1ページが表示されます。このページは空で返されます。このケースを区別するにも、やはり行数を数える必要があります。)

`Per page`には1ページに含める行数が表示され、同じ方法で編集できます。値をクリックして別の値を入力します。この値は、結果を一度に表示できる上限を超えることはできません。より大きなページではテーブルが切り捨てる行まで返され、次のページはその先から始まるため、ページングを続けると表示しきれなかった行が通知なくスキップされます。より大きな数値を指定した場合はこの上限が採用され、その値が表示されます。ページサイズを変更すると、ページごとに含まれる行が変わるため、最初のページから再開されます。

ソートまたはフィルターを変更すると、最初のページに戻ります。どちらも結果に含まれる行やその順序を変更するため、ユーザーが表示していたページはもはや同じ範囲を示しません。

<div id="how-it-is-applied">
  ## 適用方法
</div>

この形状は、[`order`](/docs/ja/reference/settings/session-settings/other#order)、[`filter`](/docs/ja/reference/settings/session-settings/other#filter)、[`limit`](/docs/ja/reference/settings/session-settings/other#limit)、[`page`](/docs/ja/reference/settings/session-settings/other#page) のクエリ構築設定として送信されます。サーバーはクエリのテキストではなくパース済みクエリにこれらを適用するため、既存のクエリの構造と組み合わせて使用できます。`UNION`、末尾の `FORMAT` 句、クエリ独自の `ORDER BY` や `LIMIT` はすべて引き続き機能し、エディタ内のクエリが書き換えられることはありません。

カラム名は引用符で囲まれた識別子として渡されるため、名前が式 (`count()`) である結果カラムや、名前にスペースを含む結果カラムも、ソートやフィルターのキーとして使用できます。

<div id="when-it-is-available">
  ## 利用できる場合
</div>

整形設定を利用できるのは、これらの設定で整形を設定できるステートメント、つまり `SELECT` および `UNION` クエリ (`WITH` 句または `FROM` で始まるクエリを含む) だけです。`SHOW`、`DESCRIBE`、`EXISTS`、`EXPLAIN` では利用できません。これらもテーブルを返しますが、設定の対象外であるため、ここでコントロールを表示すると、実際には存在しないカラムに対する結果を期待させることになります。

整形は単一のステートメントの結果に適用されるため、複数のステートメントを実行する「Run all」では利用できません。各ステートメントは、それぞれ異なるカラムを持つ個別のクエリだからです。

また、最初のページで最大 1 行しかない結果に対しても利用できません。1 行だけでは、どのように並べ替えても順序は変わらず、フィルターを適用しても行を残すか除外するかしかできません。そのため、コントロールでできるのは、同じ行を返すクエリを再実行することだけです。空の結果には、除外する行すらありません。これは、そこでは [色分け](/docs/ja/concepts/features/interfaces/web-ui-color-coding) のトグルも非表示になるのと同じ理由です。1 行以下では比較する対象がないためです。

ただし、次の 2 種類の 1 行の結果ではコントロールが維持されます。これらの場合、コントロールが元に戻す唯一の手段だからです。

* すでにソートまたはフィルタリングされている結果。ソートは元に戻せる必要があり、フィルターは解除できる必要があります。1 行に一致するフィルターは、長い結果を短い結果にする方法そのものであり、それとともにコントロールを取り除くと、ユーザーはそれが有効な状態から戻れなくなります。
* 表示上限で切り詰められた結果。これはより長い結果の最初のページです。ページサイズはテーブルが一度に表示できるセル数によって上限が決まるため、非常に wide な結果では 1 行に切り詰められることがあります。その先の行こそ、ソートとページングで到達する対象です。

整形は、設定したステートメントに紐付きます。クエリを編集した場合や、複数ステートメントのエディタでカーソルを別のステートメントに移動した場合に別のステートメントを実行すると、新しいステートメントには存在しない可能性があるカラムに `ORDER BY` や `WHERE` を適用する代わりに、整形は解除されます。

また、整形はそのステートメントを実行したコンテキストにも紐付きます。具体的には、選択したデータベース、送信先のサーバーとユーザー、クエリパラメータの値です。これらのいずれかが変わると、同じテキストでも異なるカラムを指すことになります。たとえば、データベースを切り替えた後の `SELECT * FROM events` や、パラメータを編集した後の `SELECT * FROM {tbl:Identifier}` が該当します。そのため、この場合も整形は解除され、次回の実行では整形されていない結果が返されます。

<div id="downloading-and-copying">
  ## ダウンロードとコピー
</div>

ダウンロードでは、同じ形状の生成元クエリを再実行するため、エクスポートされたファイルには画面上の結果と同じ行が同じ順序で含まれます。コピーでは表示された結果を使用するため、同様に一致します。

<div id="persistence">
  ## 永続化
</div>

形状は、ページ URL (`sort_columns`、`filters`、`page`、`page_size`) 、ブラウザの履歴、およびタブごとの結果スナップショットに保存されます。そのため、ページを再読み込みしたり、リンクを共有したり、戻る・進む操作を行ったりしても維持されます。形状は表示方法だけでなく行そのものを決定するため、クエリを自動実行する共有リンク (`run=1`) では同じ形状でクエリが再実行され、結果自体も再現されます。これらをコンパクトに保つため、保存されるのはアクティブな形状のみです。形状がない結果では、URL や履歴の状態に何も追加されません。

上記のとおり、復元された結果では、その結果を生成したコンテキストに形状が紐付いたままになります。スナップショットには、行の生成に使用されたデータベース、接続、パラメータ値が記録されるため、これらのいずれかを変更してからステートメントを再実行すると、異なる結果に形状を適用するのではなく、形状が破棄されます。

[色分けモード](/docs/ja/concepts/features/interfaces/web-ui-color-coding)および[ピン留めされたカラム](/docs/ja/concepts/features/interfaces/web-ui-pinned-columns)と同様に、形状はクエリタブごとに保持されるため、あるタブで結果をソートまたはフィルタリングしても、別のタブの結果が再実行されることはありません。

<div id="limitations">
  ## 制限事項
</div>

* サーバーが適用できない形状ではクエリが失敗し、他の失敗したクエリと同様にエラーが表示されます。失敗した実行では、それをクリアするためのヘッダーもページャーも表示されないため、その形状は削除されます。
* ソートとフィルタリングでは、結果内の名前でカラムを識別します。結果には同じ名前のカラムが複数含まれることがあります (`SELECT 1 AS x, 2 AS x`、カラム名を共有するテーブルの結合) 。このようなカラムは名前で区別できないため、ソートやフィルタのコントロールは表示されません。同じ結果内で一意の名前を持つカラムには、引き続きそれぞれのコントロールが表示されます。
* 複数カラムのソートには<kbd>Shift</kbd>キーが必要なため、タッチデバイスでは利用できません。単一カラムのソートは利用できます。
* 単一行の結果を垂直レイアウト (転置) で表示する場合、カラムヘッダーがないためコントロールもありません。このため、ユーザーがすでに形状を設定した結果は横方向レイアウトを維持します。
