Desidero scrivere una stored procedure che ottiene un array come parametro di input e ordina tale array e restituisce l'array ordinato.Ordinamento degli elementi dell'array
Gentile aiuto.
Desidero scrivere una stored procedure che ottiene un array come parametro di input e ordina tale array e restituisce l'array ordinato.Ordinamento degli elementi dell'array
Gentile aiuto.
basta usare la funzione di unnest():
SELECT
unnest(ARRAY[1,2]) AS x
ORDER BY
x DESC;
Vedi array functions nella documentazione Pg.
In PostrgreSQL 8.4 e fino è possibile utilizzare:
select array_agg(x) from (select unnest(ARRAY[1,5,3,7,2]) AS x order by x) as _;
Ma non sarà molto veloce.
In Postgres anziani è possibile implementare unnest come questo
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS SETOF anyelement AS
$BODY$
SELECT $1[i] FROM
generate_series(array_lower($1,1),
array_upper($1,1)) i;
$BODY$
LANGUAGE 'sql' IMMUTABLE
E array_agg come questo:
CREATE AGGREGATE array_agg (
sfunc = array_append,
basetype = anyelement,
stype = anyarray,
initcond = '{}'
);
ma sarà ancora più lento.
È anche possibile implementare qualsiasi algoritmo di ordinamento in pl pgsql/o qualsiasi altra lingua è possibile collegare a postgres.
questo ha lavorato per me dal http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks_I#General_array_sort
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(
SELECT $1[s.i] AS "foo"
FROM
generate_series(array_lower($1,1), array_upper($1,1)) AS s(i)
ORDER BY foo
);
$$;
Si prega di consultare la risposta di Craig dato che è molto più più informato su Postgres e ha una risposta migliore. Inoltre, se possibile, vota per eliminare la mia risposta.
Ho ricevuto l'articolo wiki aggiornato con alcune tecniche più moderne, quindi per favore usa il codice nell'articolo (o vedi la mia risposta), non quello più vecchio mostrato qui. –
Molto bella mostra delle funzionalità di PostgreSQL è procedura generale per l'ordinamento di David Fetter.
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(
SELECT $1[s.i] AS "foo"
FROM
generate_series(array_lower($1,1), array_upper($1,1)) AS s(i)
ORDER BY foo
);
$$;
@MartijnPieters Notate che è la stessa risposta della mia ma ho risposto un anno fa e ho fatto riferimento a dove l'ho presa. –
@AdamGent: Penso di averlo trovato nella prima coda di risposta e di aver riformattato l'SQL solo per renderlo leggibile. In altre parole, non avevo alcun contesto diverso dalla formattazione illeggibile. –
Il modo migliore per ordinare un array di interi è senza dubbio usare il intarray extension, che farà molto, molto, molto più veloce di qualsiasi formulazione SQL:
CREATE EXTENSION intarray;
SELECT sort(ARRAY[4,3,2,1]);
Una funzione che funziona per qualsiasi tipo di array è:
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(SELECT unnest($1) ORDER BY 1)
$$;
(ho sostituito la mia versione con Pavel's slightly faster one dopo la discussione altrove).
Craig Ho votato per cancellare la mia risposta, ma per qualche motivo non posso auto-terminare;). Così ho preso nota per vedere la tua risposta. –
Se non ho sbagliato, la funzione 'array_sort()' deve essere definita con il tag 'STABLE' (o forse' IMMUTABLE') dopo il secondo '$$'. Altri programmatori possono guardare a tali volatilità: etichette per suggerimenti su come funziona una data funzione. Le funzioni 'LANGUAGE SQL' sono (tipicamente) in linea con Postgres, ma non c'è nulla di male nell'aggiungere l'etichetta in entrambi i casi. – SeldomNeedy
Ricorda che 'unnest' non innesca tutti i livelli di un array: quindi se stai cercando di ordinare una matrice di array, avrai risultati inaspettati: la forma degli array viene mantenuta, ma i valori sono ordinati individualmente, non come un sotto-array. –
Se stai cercando una soluzione che funzioni su qualsiasi tipo di dati, ti consiglio di adottare l'approccio previsto allo YouLikeProgramming.com.
In sostanza, è possibile creare una procedura memorizzata (codice di seguito) che esegue l'ordinamento per te e tutto ciò che devi fare è passare l'array a quella procedura affinché venga ordinato in modo appropriato.
Ho anche incluso un'implementazione che non richiede l'uso di una stored procedure, se stai cercando la tua query per essere un po 'più trasportabile.
Creazione stored procedure
DROP FUNCTION IF EXISTS array_sort(anyarray);
CREATE FUNCTION
array_sort(
array_vals_to_sort anyarray
)
RETURNS TABLE (
sorted_array anyarray
)
AS $BODY$
BEGIN
RETURN QUERY SELECT
ARRAY_AGG(val) AS sorted_array
FROM
(
SELECT
UNNEST(array_vals_to_sort) AS val
ORDER BY
val
) AS sorted_vals
;
END;
$BODY$
LANGUAGE plpgsql;
ordinamento valori di matrice (funziona con qualsiasi matrice dati-tipo)
-- The following will return: {1,2,3,4}
SELECT ARRAY_SORT(ARRAY[4,3,2,1]);
-- The following will return: {in,is,it,on,up}
SELECT ARRAY_SORT(ARRAY['up','on','it','is','in']);
Ordinando valori di matrice senza una procedura immagazzinata
Nel seguito interrogazione ing, sostituire semplicemente ARRAY[4,3,2,1]
con la matrice o la query che restituisce un array:
WITH
sorted_vals AS (
SELECT
UNNEST(ARRAY[4,3,2,1]) AS val
ORDER BY
val
)
SELECT
ARRAY_AGG(val) AS sorted_array
FROM
sorted_vals
... o ...
SELECT
ARRAY_AGG(vals.val) AS sorted_arr
FROM (
SELECT
UNNEST(ARRAY[4,3,2,1]) AS val
ORDER BY
val
) AS vals
È più lungo, ma è migliore della soluzione di Craig? –
Non sono sicuro di aver compreso il rientro della domanda. Se è "meglio" per la tua implementazione, devi decidere. –
Bene, Craig fornisce una soluzione di lavoro a 5 linee. Quasi un anno dopo, aggiungi una risposta con una soluzione molto più lunga. Quindi immagino che la tua soluzione debba essere in qualche modo migliore o funzionare in alcuni casi in cui l'altra no. Sono un principiante di SQL (Postgre), quindi non posso giudicare, quindi chiedo. :) –
Il modo più veloce è il 'sort' funzione nel' intarray' modulo contrib. –