2011-02-01 1 views
6

Mam następujący kod, aby zwracać wiele wartości z pl/python:Jak podzielić typ na wiele kolumn w PostgreSQL?

CREATE TYPE named_value AS (
    name text, 
    value integer 
); 
CREATE or replace FUNCTION make_pair (name text, value integer) 
    RETURNS named_value 
AS $$ 
    return [ name, value ] 
$$ LANGUAGE plpythonu; 

select make_pair('egg', 4) as column; 

wyjście jest:

column 
(egg,4) 

Co chcę zrobić, to podzielić na dwa oddzielne wyjścia kolumn. W ten sposób:

column, column2 
egg, 4 

Jak to zrobić? Googled przez 1 godzinę mnie donikąd. Więc mam nadzieję, że dodam kilka słów kluczowych wyszukiwania w końcu: wielokrotnego zwracania wartości wiele wyników wielu kolumn unnest listy unnest ustawiony

Odpowiedz

6

Tak, składnia jest nieco zwariowana, wymagające dodatkowych nawiasów:

select (make_pair('egg', 4)).name 

aby dostać wiele komponentów z wyjścia natomiast tylko wywoływanie funkcji raz, można użyć sub-select:

select (x.column).name, (x.column).value from (select make_pair('egg', 4) as column) x; 
+1

Twój kod działa, ale zrób Naprawdę potrzebuję do tego selekcji? Byłem tak blisko z make_pair ("egg", 4) .name, ale to nie zadziałało. – David

+1

Możesz powiedzieć 'wybierz (make_pair ('egg', 4)). Name ', na przykład. Jeśli chcesz oba komponenty, ale tylko raz, wykonasz funkcję, myślę, że potrzebujesz sub-select. Zaktualizuję odpowiedź. – araqnid

+0

Brak konieczności wykonywania tej funkcji więcej niż jeden raz jest zdecydowanie celem. – David

1

Poniższy kod działa, aby uniknąć konieczności uruchomić funkcję dwukrotnie, a jednocześnie uniknąć podzapytanie.

CREATE TYPE named_value AS (
    name text, 
    value integer 
); 

CREATE or replace FUNCTION setcustomvariable(variablename text, variablevalue named_value) 
    RETURNS named_value 
AS $$ 
    GD[variablename] = variablevalue 
    return variablevalue 
$$ LANGUAGE plpythonu; 

CREATE or replace FUNCTION getcustomvariable(variablename text) 
    RETURNS named_value 
AS $$ 
    return GD[variablename] 
$$ LANGUAGE plpythonu; 

CREATE or replace FUNCTION make_pair (name text, value integer) 
    RETURNS named_value 
AS $$ 
    return [ name, value ] 
$$ LANGUAGE plpythonu; 

select setcustomvariable('result', make_pair('egg', 4)), (getcustomvariable('result')).name, (getcustomvariable('result')).value 
2
SELECT * FROM make_pair('egg', 4); 

a niektóre warianty:

SELECT name, value FROM make_pair('egg', 4) AS x; 


SELECT a, b FROM make_pair('egg', 4) AS x(a,b); 
+0

To bardzo eleganckie rozwiązanie, ale nie wiem, jak go użyć w moim przypadku, gdy potrzebuję uruchomić funkcję w każdym rzędzie w tabeli. Wydajność jest również dla mnie bardzo ważna. – David

2

Rozwiązanie znalazłem w użyciu dołączyć:

create table tmp (a int, b int, c int); 
insert into tmp (a,b,c) values (1,2,3), (3,4,5), (5,12,13); 
create type ispyth3 as (is_it boolean, perimeter int); 
create function check_it(int, int, int) returns ispyth3 as $$ 
    begin 
     return ($1*$1 + $2*$2 = $3*$3, $1+$2+$3); 
    end 
$$ language plpgsql; 
select * from tmp join check_it(a,b,c) on 1=1; 

ta zwraca:

a | b | c | is_it | perimeter 
---+----+----+-------+----------- 
1 | 2 | 3 | f  |   6 
3 | 4 | 5 | t  |  12 
5 | 12 | 13 | t  |  30 
(3 rows) 
+0

Innym sposobem wyrażenia łączenia krzyżowego jest użycie 'JOIN CHECK_it (a, b, c) ON TRUE' lub po prostu użyj' CROSS JOIN'. – NoelProf