sql >> Base de Datos >  >> RDS >> PostgreSQL

PostgreSQL:seleccione el recuento (*) para las filas donde se cumple una condición

Construyendo sobre su original

Su consulta original estaba en el camino correcto para excluir las filas infractoras. Acabas de tener > en lugar de = . Faltaba el paso complicado de contar.

SELECT count(*) AS ct
FROM  (
   SELECT 1
   FROM   compatibility c
   WHERE  rating_id = 1
   AND    NOT EXISTS (
      SELECT 1
      FROM   compatibility c2
      WHERE  c2.rating_id > 1
      AND   (c2.attr1_id = c.attr1_id AND c2.attr2_id = c.attr2_id OR
             c2.attr1_id = c.attr2_id AND c2.attr2_id = c.attr1_id))
   GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
   ) sub;

Más corto

Probablemente más rápido también.

SELECT count(*) AS ct
FROM  (
   SELECT 1  -- selecting more columns for count only would be a waste
   FROM   compatibility
   GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
   HAVING every(rating_id = 1)
   ) sub;

Similar a Consulta de @Clodoaldo o esta respuesta anterior con más explicación .
every(rating_id = 1) es más simple que not bool_or(rating_id > 1) , pero también excluye rating < 1 - lo que probablemente esté bien (o incluso mejor) para su caso.

MySQL actualmente no implementa (¡SQL estándar!) every() . Dado que solo desea eliminar rating_id > 1 , esta simple expresión se ajusta mejor a sus requisitos y funciona en ambos RDBMS:

HAVING max(rating_id) = 1

Más corto

Con count(*) como función agregada de ventana y sin subconsulta.

SELECT count(*) OVER () AS ct
FROM   compatibility
GROUP  BY least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
HAVING max(rating_id) = 1
LIMIT  1;

Las funciones de ventana se aplican después el paso agregado. Partiendo de esto, obtenemos dos pasos agregados realizados en un solo nivel de consulta:

  1. Doblar equivalente (atr1_id, atr2_id) , excluyendo filas donde divergen rating_id existir.
  2. Cuente las filas restantes con una función de ventana en todo el conjunto.

LIMIT 1 para obtener una sola fila (todas las filas serían idénticas).
MySQL no tiene funciones de ventana. Postgres solamente.
El más corto, no necesariamente el más rápido.

SQL Fiddle. (En la página 9.2, ya que la página 9.3 está actualmente fuera de línea).