> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentation de la clause LIMIT BY

# Clause LIMIT BY

Une requête avec la clause `LIMIT n BY expressions` sélectionne les `n` premières lignes pour chaque valeur distincte de `expressions`. La clé de `LIMIT BY` peut contenir un nombre quelconque d'[expressions](/fr/reference/syntax#expressions).

ClickHouse prend en charge les variantes de syntaxe suivantes :

* `LIMIT [offset_value, ]n BY expressions`
* `LIMIT n OFFSET offset_value BY expressions`

Lors du traitement de la requête, ClickHouse sélectionne les données triées selon la clé de tri. La clé de tri est définie explicitement à l'aide d'une clause [ORDER BY](/fr/reference/statements/select/order-by) ou implicitement comme propriété du table engine (l'ordre des lignes n'est garanti que lors de l'utilisation de [ORDER BY](/fr/reference/statements/select/order-by) ; sinon, les blocs de lignes ne seront pas ordonnés en raison du multithreading). ClickHouse applique ensuite `LIMIT n BY expressions` et renvoie les `n` premières lignes pour chaque combinaison distincte de `expressions`. Si `OFFSET` est spécifié, alors pour chaque bloc de données appartenant à une combinaison distincte de `expressions`, ClickHouse ignore `offset_value` lignes à partir du début du bloc et renvoie au maximum `n` lignes en résultat. Si `offset_value` est supérieur au nombre de lignes dans le bloc de données, ClickHouse ne renvoie aucune ligne de ce bloc.

<Note>
  `LIMIT BY` n'est pas lié à [LIMIT](/fr/reference/statements/select/limit). Les deux peuvent être utilisés dans la même requête.
</Note>

Si vous souhaitez utiliser des numéros de colonne au lieu de noms de colonnes dans la clause `LIMIT BY`, activez le paramètre [enable\_positional\_arguments](/fr/reference/settings/session-settings#enable_positional_arguments).

<div id="examples">
  ## Exemples
</div>

Table d’exemple :

```sql theme={null}
CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory;
INSERT INTO limit_by VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21);
```

Requêtes :

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  10 │
│  1 │  11 │
│  2 │  20 │
│  2 │  21 │
└────┴─────┘
```

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  11 │
│  1 │  12 │
│  2 │  21 │
└────┴─────┘
```

La requête `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` renvoie le même résultat.

La requête suivante renvoie les 5 principaux sites référents pour chaque paire `domain, device_type`, avec un maximum de 100 lignes au total (`LIMIT n BY + LIMIT`).

```sql theme={null}
SELECT
    domainWithoutWWW(URL) AS domain,
    domainWithoutWWW(REFERRER_URL) AS referrer,
    device_type,
    count() cnt
FROM hits
GROUP BY domain, referrer, device_type
ORDER BY cnt DESC
LIMIT 5 BY domain, device_type
LIMIT 100;
```

`LIMIT BY` fonctionne également avec des limites négatives et des décalages. Comme pour la [clause LIMIT négative](/fr/reference/statements/select/limit#negative-limits), vous pouvez utiliser des valeurs négatives avec `LIMIT BY` pour sélectionner des lignes depuis la *fin* de chaque groupe.

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT -2 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  11 │
│  1 │  12 │
│  2 │  20 │
│  2 │  21 │
└────┴─────┘
```

Renvoie les 2 dernières lignes pour chaque `id`. Pour `id = 1`, on obtient les lignes `11` et `12` ; pour `id = 2`, les deux lignes sont renvoyées, car le groupe ne comporte que 2 lignes.

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT -1 OFFSET -1 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  11 │
│  2 │  20 │
└────┴─────┘
```

Renvoie l’avant-dernière ligne de chaque `id` : le `OFFSET -1` final supprime la dernière ligne de chaque groupe, puis le `-1` initial conserve la dernière ligne de ce qui reste.

Il est également possible de combiner des `LIMIT` et des `OFFSET` de signes différents. Par exemple, pour supprimer la première ligne de chaque groupe, puis conserver les 2 dernières de ce qui reste :

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT -2 OFFSET 1 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  11 │
│  1 │  12 │
│  2 │  21 │
└────┴─────┘
```

Pour `id = 1`, la première ligne (`10`) est ignorée ; les 2 dernières (`11` et `12`) sont toutes deux renvoyées. Pour `id = 2`, la première ligne (`20`) est ignorée, ne laissant que `21`.

<div id="limit-by-all">
  ## LIMIT BY ALL
</div>

`LIMIT BY ALL` revient à lister toutes les expressions du SELECT qui ne sont pas des fonctions d’agrégation.

Par exemple :

```sql theme={null}
SELECT col1, col2, col3 FROM table LIMIT 2 BY ALL;
```

est identique à

```sql theme={null}
SELECT col1, col2, col3 FROM table LIMIT 2 BY col1, col2, col3;
```

Dans le cas particulier où une fonction prend à la fois des fonctions d’agrégation et d’autres champs comme arguments, les clés `LIMIT BY` contiendront l’ensemble maximal de champs non agrégés que nous pouvons en extraire.

Par exemple :

```sql theme={null}
SELECT substring(a, 4, 2), substring(substring(a, 1, 2), 1, count(b)) FROM t LIMIT 2 BY ALL;
```

est identique à

```sql theme={null}
SELECT substring(a, 4, 2), substring(substring(a, 1, 2), 1, count(b)) FROM t LIMIT 2 BY substring(a, 4, 2), substring(a, 1, 2);
```

<div id="examples">
  ## Exemples
</div>

Exemple de table :

```sql theme={null}
CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory;
INSERT INTO limit_by VALUES (1, 10), (1, 11), (1, 12), (2, 20), (2, 21);
```

Requêtes :

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  10 │
│  1 │  11 │
│  2 │  20 │
│  2 │  21 │
└────┴─────┘
```

```sql theme={null}
SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id;
```

```text theme={null}
┌─id─┬─val─┐
│  1 │  11 │
│  1 │  12 │
│  2 │  21 │
└────┴─────┘
```

La requête `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` renvoie le même résultat.

Avec `LIMIT BY ALL` :

```sql theme={null}
SELECT id, val FROM limit_by ORDER BY id, val LIMIT 2 BY ALL;
```

Cela équivaut à :

```sql theme={null}
SELECT id, val FROM limit_by ORDER BY id, val LIMIT 2 BY id, val;
```
