2016-06-14 10 views
0

ich eine Tabelle in PostgreSQL haben, die Informationen wie diese hat:aus einem Satz in einer Spalte niedrigsten Wert auswählen

ID | Value | Total 
12 | 'foo' | 16 
15 | 'loo' | 1 
13 | 'too' | 11 
67 | 'roo' | 7 

Die Abfrage, die ich entweder eine einzelne ID oder mehrere IDS gegeben werden bauen müssen, die durch Kommas sind getrennt. Nur der Wert muss zurückgegeben werden. Wenn mehrere IDs vorhanden sind, wird nur das Ergebnis des Satzes zurückgegeben, der die niedrigste Summe aufweist.

Das ist mein Anfang, aber es ist nicht genau das, was ich bin nach:

IF(position(',' in sample_id)>0) THEN 
    RETURN QUERY SELECT value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,',')); 
ELSE 
    RETURN QUERY SELECT value FROM table WHERE table.id = sample_id; 
END IF; 

EDIT: Um klar zu sein, ich eine Funktion bin Gebäude dass

CREATE OR REPLACE FUNCTION public.get_test_results(IN sample_id text) 
    RETURNS TABLE(test_result text) AS 
    $BODY$ 
    BEGIN 
     IF(position(',' in sample_id)>0) THEN 
      RETURN QUERY SELECT value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,',')); 
     ELSE 
      RETURN QUERY SELECT value FROM table WHERE table.id = sample_id; 
     END IF; 
    END; 
    $BODY$ 

Es wird verwendet, :

get_test_results("342949283940829308") 

OR

get_test_results("67, 12") 

Die ID-Werte in diesem Aufruf stimmen nicht mit der Beispieltabelle überein. Das Ergebnis sollte NUR den Wert von der niedrigsten TOTAL der IDs in der Menge zurückgeben, wenn mehr als eine ID an die Funktion übergeben wird.

+1

Beispiel gegebenen Eingabe und gewünscht aus bieten setzen – SMW

+0

'table.id = ANY (regexp_split_to_array (sample_id, '')) ; 'wird auch für einen einzelnen Wert gut funktionieren. Keine Notwendigkeit für eine "if" -Anweisung. Aber es ist völlig unklar, was Sie mit "* dem Ergebnis des Satzes, der die niedrigste Summe * hat", meinen. Bitte [bearbeiten] Sie Ihre Frage und fügen Sie die erwartete Ausgabe basierend auf einer Beispieleingabe hinzu. –

+0

Aktualisiert, um Eingabe und Ausgabe hinzuzufügen. – Lithodora

Antwort

1

Verwenden Sie einfach eine Limit-Klausel:

select value 
from the_table 
where id = ANY(regexp_split_to_array(sample_id,',')::int[]) 
order by total 
limit 1; 

Beachten Sie, dass auch das Ergebnis der regexp_split_to_array zu einem Integer-Array werfen müssen (::int[]) sonst kann man nicht any() verwenden, die Spalte mit einer ganzen Zahl zu vergleichen.

Sie benötigen dazu auch kein PL/pgSQL. Eine einfache SQL-Funktion führt:

CREATE OR REPLACE FUNCTION public.get_test_results(IN sample_id text) 
    RETURNS TABLE(test_result text) AS 
$BODY$ 
    select value 
    from the_table 
    where id = ANY(regexp_split_to_array(sample_id,',')::int[]) 
    order by total 
    limit 1; 
$BODY$ 
language sql; 

Beachten Sie, dass, wenn mehrere Zeilen mit demselben Minimalwert sind, wird die oben nur eine einzige Zeile zurück.

Wenn Sie alle Zeilen benötigen, können Sie eine Fensterfunktion verwenden können:

select value 
from (
    select value, dense_rank() over (order by total) as rnk 
    from the_table 
    where id = ANY(regexp_split_to_array(sample_id,',')::int[]) 
) t 
where rnk = 1 
1

Sie können die min(table.total) in einer geschachtelten Auswahl abrufen.

Ich benutze PostgreSQL nicht, aber wenn Ihr Beispiel gültig ist, sollten Sie schreiben:

RETURN QUERY SELECT table.value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,',')) and table.total in (
    SELECT min(tbl.total) FROM table tbl WHERE tbl.id = ANY(regexp_split_to_array(sample_id,',')) 
); 

Beachten Sie, dass, wie in einem Kommentar erwähnt, Sie brauchen nicht zu prüfen, ob Sie eine einzelne oder mehrere passieren Werte seit dem Aufteilen des Arguments funktionieren in beiden Fällen.

Verwandte Themen