sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL - vyberte počet(*) pro řádky, kde platí podmínka

Navazovat na svůj originál

Váš původní dotaz byl na správné cestě k vyloučení problematických řádků. Právě jste měli > místo = . Chyběl záludný krok k počítání.

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;

Kratší

Pravděpodobně také rychlejší.

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;

Podobné jako dotaz @Clodoaldo nebo tuto dřívější odpověď s podrobnějším vysvětlením .
every(rating_id = 1) je jednodušší než not bool_or(rating_id > 1) , ale také nezahrnuje rating < 1 - což je pro váš případ pravděpodobně v pořádku (nebo ještě lepší).

MySQL aktuálně neimplementuje (standardní SQL!) every() . Protože chcete odstranit pouze rating_id > 1 , tento jednoduchý výraz lépe vyhovuje vašim požadavkům a funguje v obou RDBMS:

HAVING max(rating_id) = 1

Nejkratší

Pomocí count(*) jako funkci agregace oken a bez poddotazu.

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;

Funkce okna se použijí po souhrnný krok. Na základě toho dostáváme dva souhrnné kroky provedené na úrovni jednoho dotazu:

  1. Ekvivalent přeložení (atr1_id, atr2_id) , kromě řádků, kde se rating_id liší existovat.
  2. Počítejte zbývající řádky pomocí funkce okna přes celou sadu.

LIMIT 1 získat jeden řádek (všechny řádky by byly identické).
MySQL nemá okenní funkce. Postgres pouze.
Nejkratší, ne nutně nejrychlejší.

SQL Fiddle. (Na str.9.2, protože pg9.3 je aktuálně offline.)



  1. OctoberCMS:Jak si udržet oboustranný přátelský vztah?

  2. Odhadovaný počet řádků ke čtení

  3. Převeďte uniklý znak Unicode zpět na skutečný znak v PostgreSQL

  4. VYBERTE všechny záznamy staré 30 dní