2014-12-06 13 views
5

Mam problem, nad którym pracuję. Poniżej znajduje się uproszczony zapytania, aby pokazać problem:PostgreSQL: Jak uzyskać dostęp do kolumny na anonimowym rekordzie

WITH the_table AS (
    SELECT a, b 
    FROM (VALUES('data1', 2), ('data3', 4), ('data5', 6)) x (a, b) 
), my_data AS (
    SELECT 'data7' AS c, array_agg(ROW(a, b)) AS d 
    FROM the_table 
) 
SELECT c, d[array_upper(d, 1)] 
FROM my_data 

W mojej sekcji danych, można zauważyć, że tworzę tablicę z wielu wierszy, a tablica jest zwrócony w jednym rzędzie z innymi danymi. Ta tablica musi zawierać informacje zarówno dla a i b i zachować dwie wartości połączone razem. Wydaje się, że sensowne byłoby użycie anonimowego wiersza lub rekordu (chcę uniknąć tworzenia typu złożonego).

Wszystko działa dobrze, dopóki nie zacznę wyciągać danych z powrotem. W powyższym przykładzie potrzebuję uzyskać dostęp do ostatniego wpisu w tablicy, co jest łatwe do wykonania przy użyciu array_upper, ale muszę uzyskać dostęp do wartości w kolumnie, która kiedyś była kolumną b, której nie mogę wymyślić.

Zasadniczo teraz powyższe zapytanie wraca:

"data7";"(data5,6)" 

I muszę wrócić

"data7";6 

Jak mogę to zrobić?

UWAGA: Podczas gdy w powyższym przykładzie używam tekstu i liczb całkowitych jako typów dla moich danych, nie są to rzeczywiste typy końcowe, ale raczej służą do uproszczenia przykładu.

UWAGA: To jest za pomocą PostgreSQL 9.2

EDIT: Dla wyjaśnienia, coś SELECT 'data7', 6 nie jest to, co ja jestem po. Wyobraźmy sobie, że tabela_testowa faktycznie pobiera dane z tabel bazy danych, a nie z instrukcji WITH, którą wstawiłem dla wygody, i nie bardzo wiem, jakie dane znajdują się w tabeli.

Innymi słowy, chcę być w stanie zrobić coś takiego:

SELECT c, (d[array_upper(d, 1)]).b 
FROM my_data 

i otrzymaj powrotem:

"data7";6 

Zasadniczo raz Włożyłam coś do anonimowego rekordu za pomocą funkcji row(), jak mogę ją wycofać? Jak podzielić część 'data5' i część 6, aby nie powróciły w jednej kolumnie?

Inny przykład:

SELECT ROW('data5', 6) 

da 'danych5' i 6 powrót w kolumnie. Jak mogę wziąć tę kolumnę i podzielić ją na dwie pierwotne?

Mam nadzieję, że wyjaśnia

+0

Dlaczego trzeba użyć tablic za to, co wygląda na proste zapytania agregacji? –

+0

To jest uproszczony przykład, aby moje pytanie było bardziej przejrzyste.Pełna kwerenda używa instrukcji rekursywnej z instrukcją do gromadzenia danych (w tym wierszy z tablicami), a następnie używam DISTINCT ON w jednej kolumnie z ORDER BY na innej kolumnie, aby wyeliminować niepotrzebne dane generowane z zapytania rekursywnego. Wszystko działa pięknie, jeśli na przykład potrzebuję tylko danych z kolumny a, ale potrzebuję zarówno a, jak i b, i nie mogę stracić ich powiązania. Gdybym używał pgsql 9.4, to bym po prostu miał aib w osobnych tablicach, a następnie używałbym multi kolumny niepoprawnie, że musi ponownie powiązać a i b później. Ale mam 9.2. –

+0

Strona, która ma podobne pytanie z odpowiedzią, która nie działa w tym przypadku, można znaleźć tutaj: http://www.postgresql.org/message-id/[email protected] com –

Odpowiedz

1

Jeśli można zainstalować rozszerzenie hstore:

with the_table as (
    select a, b 
    from (values('data1', 2), ('data3', 4), ('data5', 6)) x (a, b) 
), my_data as (
    select 'data7' as c, array_agg(row(a, b)) as d 
    from the_table 
) 
select c, (avals(hstore(d[array_upper(d, 1)])))[2] 
from my_data 
; 
    c | avals 
-------+------- 
data7 | 6 
+0

Jest to zasadniczo dokładnie to, czego szukam, z wyjątkiem faktu, że musisz pobrać rozszerzenie, aby działało. Nie wiem, po prostu uważam, że to głupie, że możesz zbudować strukturę, której nie możesz rozebrać, chyba że użyjesz rozszerzenia. W każdym razie dam ci teraz awans i jeśli nikt nie przyjdzie z bardziej natywnym rozwiązaniem (bez rozszerzeń), to zaakceptuję twoją odpowiedź. –

+0

Pytanie dla ciebie. Czy wiesz, w jaki sposób metoda avals umieszcza dwa różne typy danych w tej samej tablicy? Większość informacji w Internecie mówi, że nie możesz mieć tablicy o różnych typach, ale avals wydaje się na to zezwalać. –

+0

Czekaj, znalazłem odpowiedź na moje własne pytanie. Zamienia wszystko na tekst i używa tablicy tekstowej. To działa na moim przykładzie z tekstem i liczbami całkowitymi, ale może na przykład stać się bardziej kłopotliwe w pracy z typami złożonymi. Wolałbym znaleźć coś, co zachowuje typy, jeśli to w ogóle możliwe. –

Powiązane problemy