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

Berechnen Sie Prozente aus SUM() in derselben SELECT-SQL-Abfrage

Hinter dieser Frage steckt mehr, als es den Anschein haben mag.

Einfache Version

Das ist viel schneller und einfacher:

SELECT property_name
      ,(count(value_a = value_b OR NULL) * 100) / count(*) AS pct
FROM   my_obj
GROUP  BY 1;

Ergebnis:

property_name | pct
--------------+----
 prop_1       | 17
 prop_2       | 43

Wie?

  • Dafür brauchst du überhaupt keine Funktion.

  • Statt value_b zu zählen (was Sie nicht brauchen) und die Summe zu berechnen, verwenden Sie count(*) für die Summe. Schneller, einfacher.

  • Dies setzt voraus, dass Sie NULL nicht haben Werte. D.h. beide Spalten sind definiert NOT NULL . Die Informationen fehlen in Ihrer Frage.
    Falls nicht, tut Ihre ursprüngliche Anfrage wahrscheinlich nicht das, was Sie denken . Wenn einer der Werte NULL ist, zählt Ihre Version diese Zeile überhaupt nicht. Sie könnten sogar eine Division durch Null provozieren Ausnahme auf diese Weise.
    Diese Version funktioniert auch mit NULL. count(*) erzeugt die Anzahl aller Zeilen, unabhängig von Werten.

  • So funktioniert die Zählung:

     TRUE  OR NULL = TRUE
     FALSE OR NULL = NULL
    

    count() ignoriert NULL-Werte. Voilá.

  • Die Operatorpriorität regelt diesen = bindet vor OR . Sie könnten Klammern hinzufügen, um es klarer zu machen:

    count ((value_a = value_b) OR FALSE)
    
  • Dasselbe können Sie mit

    tun
    count NULLIF(<expression>, FALSE)
    
  • Der Ergebnistyp von count() ist bigint standardmäßig.
    Eine Division bigint / bigint , kürzt Nachkommastellen .

Nachkommastellen einbeziehen

Verwenden Sie 100.0 (mit Nachkommastellen), um die Berechnung numeric zu erzwingen und dabei Nachkommastellen beibehalten.
Vielleicht möchten Sie round() verwenden damit:

SELECT property_name
      ,round((count(value_a = value_b OR NULL) * 100.0) / count(*), 2) AS pct
FROM   my_obj
GROUP  BY 1;

Ergebnis:

property_name | pct
--------------+-------
 prop_1       | 17.23
 prop_2       | 43.09

Nebenbei:
Ich verwende value_a statt valueA . Verwenden Sie in PostgreSQL keine Bezeichner ohne Anführungszeichen mit gemischter Groß-/Kleinschreibung. Ich habe zu viele verzweifelte Fragen aus dieser Torheit kommen sehen. Wenn Sie sich fragen, wovon ich spreche, lesen Sie das Kapitel Identifikatoren und Schlüsselwörter im Handbuch.