web-dev-qa-db-fra.com

Comptage des lignes d'une sous-requête

Simple: je voudrais compter le nombre de lignes de la sous-requête. Notez que status indique si l'hôte est en ligne ou non.

Mauvais code

SELECT COUNT(ip_address) FROM `ports` (
    SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
)

Expliqué

La première requête, lorsqu'elle est exécutée seule, renvoie ceci:

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
ip_address  
192.168.1.1
192.168.1.2
192.168.1.248
192.168.1.251
192.168.1.254

La deuxième requête exécutée seule retourne ceci:

SELECT COUNT(ip_address) FROM `ports`
17

Question

Je voudrais savoir comment compter cette liste de 5 adresses IP.

J'ai cherché en ligne des solutions possibles à ce problème simple et je suis simplement frustré, alors j'ai pensé demander aux experts.

13
rwcommand

Pour répondre à votre question immédiate, comment compter les lignes d'une sous-requête, la syntaxe est la suivante:

SELECT COUNT(*) FROM (subquery) AS some_name;

La sous-requête doit immédiatement suivre le mot clé FROM. (Dans MySQL, il est également obligatoire d'attribuer un nom à une sous-requête de ce type (il s'agit en fait d'une table dérivée ), c'est pourquoi vous pouvez voir le AS some_name en le suivant.) Comme vous l'avez écrit, MySQL interprète votre script comme deux requêtes indépendantes, c'est pourquoi vous obtenez deux jeux de résultats.

Donc, puisque la sous-requête dans votre cas est

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE

la requête complète ressemblerait à ceci:

SELECT COUNT(*) FROM (
    SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
) AS derived;

Mais, comme Julien l'a suggéré , vous pouvez réécrire votre requête comme ceci:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

De cette façon, vous n'avez pas du tout besoin d'une table de sous-requête/dérivée, car la fonction COUNT ne comptera que les occurrences distinctes de ip_address dans la table ports.

18
Andriy M

Vous devez déplacer le DISTINCT vers la COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

Cela renvoie 5 car il ne compte que des valeurs distinctes et la sous-requête n'est plus nécessaire.

Cependant, cette requête renvoie 17 car il y a 17 lignes dans la table ports:

SELECT COUNT(ip_address) FROM `ports`;

Voir ceci SQL Fiddle .

Exemples de données avec 17 lignes et 5 adresses IP distinctes:

CREATE TABLE ports (ip_address varchar(20));

INSERT INTO `ports`(ip_address) VALUES
  ('192.168.1.1')
  , ('192.168.1.1')
  , ('192.168.1.1')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.251')
  , ('192.168.1.251')
  , ('192.168.1.251')
  , ('192.168.1.254')
  , ('192.168.1.254')
  , ('192.168.1.254');
6
Julien Vavasseur