sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL - välj count(*) för rader där ett villkor gäller

Byggar på ditt original

Din ursprungliga fråga var på rätt väg för att utesluta stötande rader. Du hade precis > istället för = . Det knepiga steget att räkna saknades.

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;

Kortare

Förmodligen snabbare också.

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;

Liknar @Clodoaldos fråga eller detta tidigare svar med mer förklaring .
every(rating_id = 1) är enklare än not bool_or(rating_id > 1) , men utesluter också rating < 1 - vilket förmodligen är bra (eller ännu bättre) för ditt fall.

MySQL implementerar för närvarande inte (standard SQL!) every() . Eftersom du bara vill ta bort rating_id > 1 , detta enkla uttryck passar dina krav bättre och fungerar i båda RDBMS:

HAVING max(rating_id) = 1

Kortast

Med count(*) som fönsteraggregatfunktion och utan underfråga.

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;

Fönsterfunktioner tillämpas efter det sammanlagda steget. Med utgångspunkt i detta får vi två samla steg gjorda på en enda frågenivå:

  1. Vik motsvarande (atr1_id, atr2_id) , exklusive rader där rating_id avviker finns.
  2. Räkna återstående rader med en fönsterfunktion över hela uppsättningen.

LIMIT 1 för att få en enda rad (alla rader skulle vara identiska).
MySQL har inga fönsterfunktioner. Postgres bara.
Kortast, inte nödvändigtvis snabbast.

SQL-fiol. (På pg9.2 eftersom pg9.3 för närvarande är offline.)



  1. Oracle RAC VIP och ARP Primer

  2. MySQL Cluster (NDB) vs MySQL Replication (InnoDB) för Rails 3-appar:fördelar/nackdelar?

  3. android fjärrdatabas anslutning problem

  4. hur man konverterar ett strängdatum till datumformat i oracle10g