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

Entschachteln Sie mehrere Arrays parallel

Sie werden lieben diese neue Funktion von Postgres 9.4 :

unnest(anyarray, anyarray [, ...])

unnest() mit der (zumindest von mir) lang erwarteten Fähigkeit, mehrere Arrays parallel sauber zu entschachteln . Das Handbuch:

Erweitern Sie mehrere Arrays (möglicherweise unterschiedlichen Typs) zu einer Reihe von Zeilen. Dies ist nur in der FROM-Klausel zulässig;

Es ist eine spezielle Implementierung des neuen ROWS FROM Funktion.

Ihre Funktion kann jetzt nur noch sein:

CREATE OR REPLACE FUNCTION multi_unnest(_some_id int
                                      , _amounts numeric[]
                                      , _invoices text[])
  RETURNS TABLE (some_id int, amount numeric, invoice text) AS
$func$
SELECT _some_id, u.* FROM unnest(_amounts, _invoices) u;
$func$ LANGUAGE sql;

Aufruf:

SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[] 
                        , '{01-2222-05,01-3333-04,01-4444-08}'::text[]);

Natürlich kann die einfache Form durch plain SQL ersetzt werden (keine Zusatzfunktion):

SELECT 123 AS some_id, *
FROM unnest('{100, 40.5, 76}'::numeric[]
          , '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);

In früheren Versionen (Postgres 9.3- ), können Sie die weniger elegante und weniger sichere Form verwenden:

SELECT 123 AS some_id
     , unnest('{100, 40.5, 76}'::numeric[]) AS amount
     , unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;

Vorbehalte der alten Kurzform:Abgesehen davon, dass es nicht standardmäßig ist, eine Set-Returning-Funktion in SELECT zu haben list, wäre die Anzahl der zurückgegebenen Zeilen das kleinste gemeinsame Vielfache der Anzahl der Elemente jedes Arrays (mit überraschenden Ergebnissen für ungleiche Zahlen). Details in diesen verwandten Antworten:

  • Paralleles Unnest() und Sortierreihenfolge in PostgreSQL
  • Gibt es in PostgreSQL so etwas wie eine zip()-Funktion, die zwei Arrays kombiniert?

Dieses Verhalten wurde endlich mit Postgres 10 bereinigt . Mehrere Set-Returning-Funktionen im SELECT list erzeugt jetzt Zeilen im "lock-step". Siehe:

  • Was ist das erwartete Verhalten für mehrere Set-zurückgebende Funktionen in der SELECT-Klausel?