PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Haben alle Gruppen die gleiche Gesamtmacht für eine bestimmte Untergruppe?

Lesen Sie die Frage sorgfältig durch

Und:

Der wichtige Punkt für die Leistung besteht darin, irrelevante Zeilen frühzeitig auszuschließen und nur Aggregate für die angegebene Untergruppe zu berechnen . Dann (unter der Annahme von mehr als ein paar unterschiedlichen Untergruppen) ein Index für (subgroup) kann helfen:

CREATE INDEX ON foo (subgroup);

Jede der folgenden Abfragen gibt FALSE zurück wenn mindestens zwei Gruppen unterschiedliche Gesamtsummen für die gegebene Untergruppe haben, und TRUE in alle andere Fälle (mit einer geringfügigen Ausnahme für Abfrage 5, siehe unten).

Abfrage 1

SELECT count(DISTINCT total_power) = 1
FROM  (
   SELECT sum(power) AS total_power
   FROM   foo
   WHERE  subgroup = 'Sub_B'  -- exclude irrelevant rows early!
   GROUP  BY grp
   ) sub;

Abfrage 2

SELECT count(*) = 1
FROM  (
   SELECT true
   FROM  (
      SELECT sum(power) AS total_power
      FROM   foo
      WHERE  subgroup = 'Sub_C'
      GROUP  BY grp
      ) sub2
   GROUP  BY total_power
   ) sub2;

Abfrage 3

SELECT count(*) OVER () = 1
FROM  (
   SELECT sum(power) AS total_power
   FROM   foo
   WHERE  subgroup = 'Sub_A'
   GROUP  BY grp
   ) sub
GROUP  BY total_power
LIMIT  1;

Abfrage 4

(
SELECT FALSE
FROM  (
   SELECT sum(power) AS total_power
   FROM   foo
   WHERE  subgroup = 'Sub_A'
   GROUP  BY grp
   ) sub
GROUP  BY total_power
OFFSET 1
LIMIT  1
)
UNION ALL
SELECT TRUE
LIMIT 1;

Dieser ist etwas Besonderes. Verwandte Antworten mit Erklärung:

Abfrage 5

SELECT min(total_power) = max(total_power)  -- can fail for NULL values
FROM  (
   SELECT sum(power) AS total_power
   FROM   foo
   WHERE  subgroup = 'Sub_A'
   GROUP  BY grp
   ) sub;

Der letzte kann fehlschlagen, wenn NULL Potenzwerte sind erlaubt. (Aber Sie müssten in diesem Fall ohnehin erwartete Ergebnisse definieren.)

Ich habe einen umfangreichen Test durchgeführt und festgestellt, dass alle Abfragen unter idealen Bedingungen ungefähr gleich ausgeführt werden:

db<>fiddle hier

Abfrage 5 war tendenziell etwas schneller als die anderen.