sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL - vælg antal(*) for rækker, hvor en betingelse gælder

Bygger på din original

Din oprindelige forespørgsel var på rette vej for at ekskludere stødende rækker. Du har lige haft > i stedet for = . Det vanskelige trin at tælle manglede.

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;

Kortere

Sandsynligvis også hurtigere.

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;

Svarer til @Clodoaldos forespørgsel eller dette tidligere svar med mere forklaring .
every(rating_id =1) er enklere end ikke bool_or(rating_id> 1) , men udelukker også rating <1 - hvilket sikkert er fint (eller endnu bedre) for dit tilfælde.

MySQL implementerer ikke i øjeblikket (standard SQL!) every() . Da du kun ønsker at fjerne rating_id> 1 , dette enkle udtryk passer bedre til dine krav og fungerer i begge RDBMS:

HAVING max(rating_id) = 1

Korteste

Med count(*) som vinduesaggregatfunktion og uden underforespørgsel.

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;

Vinduesfunktioner anvendes efter det samlede trin. Med udgangspunkt i dette får vi to aggregerede trin udført på et enkelt forespørgselsniveau:

  1. Fold tilsvarende (atr1_id, atr2_id) , undtagen rækker, hvor rating_id er divergerende eksisterer.
  2. Tæl resterende rækker med en vinduesfunktion over hele sættet.

LIMIT 1 for at få en enkelt række (alle rækker ville være identiske).
MySQL har ikke vinduesfunktioner. Postgres kun.
Korteste, ikke nødvendigvis hurtigst.

SQL Fiddle. (På pg9.2, da pg9.3 i øjeblikket er offline.)



  1. MYSQL adgangskontrol

  2. node-mysql fejl:tilslut ECONNREFUSED

  3. Skjul SQL>-sætninger i spool-filen

  4. Jeg har forskellige resultater fra forespørgsel for COUNT('e.id') eller COUNT(e.id)