Approfondissement de la fonction COUNT

SyntaxeCOUNT(*)

  • COUNT(*)renvoie le nombre de lignes de la relation.

  • COUNT(a)renvoie le nombre de valeurs non nulles de la relation (donc COUNT(*) et COUNT(a) sont équivalents si a est non null)

  • COUNT (DISTINCT a) renvoie le nombre de valeurs non nulles et distinctes de la relation

Exemple

1
CREATE TABLE t (
2
pk INTEGER PRIMARY KEY,
3
a VARCHAR(1),
4
b VARCHAR(1));
5
INSERT INTO t VALUES (1, 'a', 'x');
6
INSERT INTO t VALUES (2, 'a', 'y');
7
INSERT INTO t VALUES (3, 'b', NULL);
table t

#pk

a NOT NULL

b

1

a

x

2

a

y

3

b

  • SELECT COUNT(*) FROM t : 3

  • SELECT COUNT(pk) FROM t : 3

  • SELECT COUNT(a) FROM t : 3

  • SELECT COUNT (DISTINCT a) FROM t : 2

  • SELECT COUNT(*) FROM t GROUP BY a : 2

Attention

Pour des raisons de performance, on préfère l'usage d'un GROUP BY à COUNT (DISTINCT a). On utilise ce dernier que s'il n'existe pas de solution ne mobilisant qu'une seule requête.

Exemple

1
SELECT COUNT(*) AS nb_total, COUNT (DISTINCT a) AS nb_a FROM t;
1
 nb_total | nb_a 
2
----------+------
3
        3 |    2

AttentionCOUNT(*) et résultat de requête

Il faut prendre garde à l'usage de COUNT(*) dès que l'on adresse des requêtes portant sur plusieurs tables, en effet cela comptera toutes les lignes produite par le produit cartésien, ce qui n'est pas toujours ce que l'on souhaite.

On préférera compter un attribut non nul.

ExempleCOUNT(*) et jointure externe

Soit la séquence suivante permettant d'instancier t1 et t2, tel que référence t1 référence t2 et qu'il existe un élément de t2 qui n'est jamais référencé.

1
CREATE TABLE t2 (
2
pk INTEGER PRIMARY KEY,
3
a VARCHAR
4
);
5
6
CREATE TABLE t1 (
7
pk VARCHAR PRIMARY KEY,
8
fk INTEGER REFERENCES t2(pk)
9
);
10
11
INSERT INTO t2 VALUES (1, 'x');
12
INSERT INTO t2 VALUES (2, 'x');
13
14
INSERT INTO t1 VALUES ('a',1);
15
INSERT INTO t1 VALUES ('b',1);

Si l'on utilise un COUNT(*) alors on obtient la valeur 1 pour b au lieu du 0 escompté :

  • la ligne (b,NULL) est ajoutée au résultat parce que b n'est jamais référencé (principe de la jointure externe)

  • étant donné que la jointure externe a lieu avant le regroupement et que COUNT(*) compte toutes les lignes

1
SELECT t2.pk, COUNT(*) 
2
FROM t2 
3
LEFT JOIN t1 ON t1.fk=t2.pk
4
GROUP BY t2.pk;
1
 pk | count 
2
----+-------
3
  1 |     2
4
  2 |     1

Si l'on utilise un COUNT(a) sur la clé de la table t1, celle-ci étant nulle dans le cas des lignes ajoutées par la jointure externe, le fonctionnement est celui attendu.

1
SELECT t2.pk, COUNT(t1.pk) 
2
FROM t2 
3
LEFT JOIN t1 ON t1.fk=t2.pk
4
GROUP BY t2.pk;
1
 pk | count 
2
----+-------
3
  1 |     2
4
  2 |     0