PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Oblicz procenty z SUM() w tym samym zapytaniu SELECT sql

W tym pytaniu jest więcej, niż mogłoby się wydawać.

Prosta wersja

To dużo szybciej i prościej:

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

Wynik:

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

Jak?

  • W ogóle nie potrzebujesz do tego funkcji.

  • Zamiast liczyć value_b (od czego nie musisz zaczynać) i obliczając sumę, użyj count(*) za całość. Szybciej, prościej.

  • Zakłada się, że nie masz NULL wartości. Tj. obie kolumny są zdefiniowane NOT NULL . Brakuje informacji w Twoim pytaniu.
    Jeśli nie, pierwotne zapytanie prawdopodobnie nie robi tego, co Twoim zdaniem robi . Jeśli którakolwiek z wartości ma wartość NULL, Twoja wersja w ogóle nie liczy tego wiersza. Możesz nawet sprowokować dzielenie przez zero wyjątek w ten sposób.
    Ta wersja działa również z NULL. count(*) generuje liczbę wszystkich wierszy, niezależnie od wartości.

  • Oto jak działa licznik:

     TRUE  OR NULL = TRUE
     FALSE OR NULL = NULL
    

    count() ignoruje wartości NULL. Voila.

  • Pierwszeństwo operatora określa, że ​​= wiąże przed OR . Możesz dodać nawiasy, aby było jaśniej:

    count ((value_a = value_b) OR FALSE)
    
  • Możesz zrobić to samo z

    count NULLIF(<expression>, FALSE)
    
  • Typ wyniku count() jest bigint domyślnie.
    Dział bigint / bigint , obcina cyfry ułamkowe .

Uwzględnij cyfry ułamkowe

Użyj 100.0 (z cyfrą ułamkową), aby wymusić obliczenie jako numeric i tym samym zachować cyfry ułamkowe.
Możesz użyć round() z tym:

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

Wynik:

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

Na marginesie:
Używam value_a zamiast valueA . Nie używaj niecytowanych identyfikatorów z mieszanymi literami w PostgreSQL. Widziałem zbyt wiele rozpaczliwych pytań wynikających z tego szaleństwa. Jeśli zastanawiasz się, o czym mówię, przeczytaj rozdział „Identyfikatory i słowa kluczowe” w podręczniku.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak tworzyć dynamiczne deklaracje postgresowe w PHP

  2. Iterowanie po liczbach całkowitych [] w PL/pgSQL

  3. Wykryj, czy wiersz został zaktualizowany lub wstawiony

  4. Czy typ danych Postgres NUMERIC może przechowywać podpisane wartości?

  5. pgFincore 1.2, rozszerzenie PostgreSQL