sql >> Database >  >> RDS >> PostgreSQL

Hoe een waarde van een functie te retourneren als er geen waarde is gevonden

Uitleg

De kern van het probleem is de vage definitie van "niets".

NULL is niet niets , het is alleen niet bekend wat het precies is. "Niets" in termen van SQL zou zijn geen rij :er wordt helemaal niets geretourneerd. Dat gebeurt meestal als er geen rij wordt gevonden. Maar bij gebruik van geaggregeerde functies , dat kan niet gebeuren omdat, per documentatie:

avg() retourneert NULL wanneer er geen rijen worden gevonden (dus niet "niets"). Je krijgt een rij met een NULL waarde als resultaat - dat overschrijft uw init-waarde in de code die u demonstreert.

Oplossing

Wikkel het resultaat in COALESCE . Een veel eenvoudigere SQL-functie demonstreren:

CREATE OR REPLACE FUNCTION get_height_sql(firstn varchar, lastn varchar)
  RETURNS float AS
$func$
   SELECT COALESCE(AVG(((p.h_feet * 12) + p.h_inches) * 2.54)::float, 0)
   FROM   player p
   WHERE  p.firstname = firstn
   AND    p.lastname = lastn
$func$  LANGUAGE sql STABLE;

SQL Fiddle.

Hetzelfde kan worden gebruikt in een plpgsql-functie. Deze functie kan STABLE . zijn , kan helpen bij de prestaties in de context van grotere zoekopdrachten.

Andere gevallen

Als je echt kunt krijg geen rij van een zoekopdracht, een eenvoudige COALESCE zou mislukken , omdat het nooit wordt uitgevoerd.

Voor een enkele waarde resultaat, je kunt de hele zoekopdracht gewoon inpakken zoals:

SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result

PL/pgSQL heeft de mogelijkheid om te controleren voordat het daadwerkelijk terugkeert van de functie. Dit werkt voor meerdere rijen met een of meer kolommen , te. Er is een voorbeeld in de handleiding demonstreren van het gebruik van FOUND :

...
RETURN QUERY SELECT foo, bar ...;

IF NOT FOUND THEN
    RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...

Gerelateerd:

Altijd precies één rij teruggeven , kunt u ook pure SQL . gebruiken :

SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;

Als de eerste SELECT geeft geen rij terug, de tweede SELECT geeft een rij met standaardwaarden terug.



  1. Oracle-query geeft fout

  2. Tabellen samenvoegen met LIKE (SQL)

  3. Django SearchVector met icontains

  4. Hoe de som van meerdere kolommen in PostgreSQL te berekenen?