Contando filas de una subconsulta

13

Simple: me gustaría contar el número de filas de la subconsulta. Tenga en cuenta que el estado es si el host está en línea o no.

Código malo

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

Explicado

La primera consulta, cuando se ejecuta por sí sola, devuelve esto:

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 segunda consulta ejecutada por sí sola devuelve esto:

SELECT COUNT(ip_address) FROM `ports`
17

Pregunta

Me gustaría saber cómo contar esa lista de 5 direcciones IP.

He estado buscando en línea posibles soluciones a este simple problema y me estaba frustrando, así que pensé en preguntar a los expertos.

rwcommand
fuente

Respuestas:

18

Para responder a su pregunta inmediata, cómo contar las filas de una subconsulta, la sintaxis es la siguiente:

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

La subconsulta debe seguir inmediatamente la palabra clave FROM. (En MySQL también es obligatorio asignar un nombre a una subconsulta de este tipo (en realidad se llama una tabla derivada ), por eso puede ver lo AS some_namesiguiente). La forma en que lo ha escrito, MySQL interpreta su script como dos consultas independientes, es por eso que obtiene dos conjuntos de resultados.

Entonces, dado que la subconsulta en su caso es

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE

la consulta completa se vería así:

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

Pero, como sugirió Julien , puede volver a escribir su consulta de esta manera:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

De esta manera, no necesita una subconsulta / tabla derivada, ya que la función COUNT contará solo las distintas apariciones de ip_addressla portstabla.

Andriy M
fuente
FY: también funcionó bien en Postgres 10: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; tuve que usar el concepto original de OP porque voy a contar las filas en una subconsulta INTERSECT.
JL Peyret
6

Debe mover el DISTINCTa COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

Esto regresa 5porque solo cuenta valores distintos y la subconsulta ya no es necesaria.

Sin embargo, esta consulta regresa 17porque hay 17 filas en la portstabla:

SELECT COUNT(ip_address) FROM `ports`;

Ver este SQL Fiddle .

Datos de muestra con 17 filas y 5 IP distintas:

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
fuente