Comptage des lignes d'une sous-requête

13

Simple: je voudrais compter le nombre de lignes de la sous-requête. Notez que l' état 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.

rwcommand
la source

Réponses:

18

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 suivre immédiatement 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 le voir ci- AS some_namedessous.) De la façon dont 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_addressdans la portstable.

Andriy M
la source
FY: a très bien fonctionné dans Postgres 10 également: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; j'ai dû utiliser le concept original OPs car je vais compter les lignes dans une sous-requête INTERSECT.
JL Peyret
6

Vous devez déplacer le DISTINCTvers COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

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

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

SELECT COUNT(ip_address) FROM `ports`;

Voir ce 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');
Julien Vavasseur
la source