sql >> Database >  >> RDS >> PostgreSQL

Bereken procenten van SUM() in dezelfde SELECT sql-query

Er is meer aan deze vraag dan het lijkt.

Eenvoudige versie

Dit is veel sneller en eenvoudiger:

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

Resultaat:

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

Hoe?

  • Hier heb je helemaal geen functie voor nodig.

  • In plaats van value_b te tellen (waar je niet mee hoeft te beginnen) en om het totaal te berekenen, gebruik je count(*) voor het totaal. Sneller, eenvoudiger.

  • Dit veronderstelt dat je geen NULL . hebt waarden. D.w.z. beide kolommen zijn gedefinieerd NOT NULL . De informatie ontbreekt in uw vraag.
    Als dat niet het geval is, doet uw oorspronkelijke zoekopdracht waarschijnlijk niet wat u denkt dat het doet . Als een van de waarden NULL is, telt uw versie die rij helemaal niet. Je zou zelfs een deling door nul kunnen uitlokken uitzondering op deze manier.
    Deze versie werkt ook met NULL. count(*) produceert de telling van alle rijen, ongeacht de waarden.

  • Zo werkt de telling:

     TRUE  OR NULL = TRUE
     FALSE OR NULL = NULL
    

    count() negeert NULL-waarden. Voilá.

  • De prioriteit van de operator bepaalt dat = bindt vóór OR . U kunt haakjes toevoegen om het duidelijker te maken:

    count ((value_a = value_b) OR FALSE)
    
  • U kunt hetzelfde doen met

    count NULLIF(<expression>, FALSE)
    
  • Het resultaattype van count() is bigint standaard.
    Een divisie bigint / bigint , knipt gebroken cijfers af .

Gedeeltelijke cijfers opnemen

Gebruik 100.0 (met fractionele cijfers) om de berekening te forceren om numeric te zijn en daardoor fractionele cijfers behouden.
Misschien wilt u round() . gebruiken hiermee:

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

Resultaat:

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

Even terzijde:
Ik gebruik value_a in plaats van valueA . Gebruik in PostgreSQL geen niet-geciteerde id's met hoofdletters. Ik heb te veel wanhopige vragen uit deze dwaasheid zien komen. Als je je afvraagt ​​waar ik het over heb, lees dan het hoofdstuk Identificaties en Sleutelwoorden in de handleiding.



  1. De bewerking is niet geldig voor de status van de transactiefout en het transactiebereik

  2. Hoe de CONCAT()-functie werkt in PostgreSQL

  3. Geef WAAR parameters door aan PostgreSQL View?

  4. De stuklijststructuur (BOM) in databases identificeren