Szukam najlepszego sposobu na przechowywanie i pobieranie tablicy danych. Rozwiązanie, które obecnie wdrażam, wykorzystuje wiele do wielu relacji w następujący sposób.

VENEUE_THEMES.

user_id  style  environment
A1A2     formal  indoor
A2B2     formal  outdoor

Theme_setting_to_setting_enum.

id  user_id  setting_enum_id
1   A1A2       1
2   A1A2       3 
3   A2B2       1 
4   A2B2       2

Ustawianie_enum

id  value
1   garden
2   beach
3   golf course
4   backyard

Pytanie, które obecnie mam:

SELECT vt.user_id, vt.style, vt.environment, se.value FROM venue_themes vt JOIN theme_settings_to_setting_enum ts ON vt.user_id = ts.user_id JOIN setting_enum se ON ts.setting_enum_id = se.id GROUP BY vt.user_id, ts.id, se.id;

Działa to, ale zwraca wiele wierszy z tymi samymi danymi innymi niż moje wartości Enum.

Przykładowym powrotem jest:

user_id    style    environment   value
AAAA       formal   indoor        beach
AAAA       formal   indoor        backyard
AAAA       formal   indoor        tent

Jest to w porządku, ale wydaje się nadmierne, jeśli mam wiele wartości. Co naprawdę chcę, aby moje dane wyglądały jak:

user_id    style    environment   value
AAAA       formal   indoor        beach, backyard, tent

Idealnie, miałbym moje wartości zwrócone w tablicy lub coś podobnego, więc nie muszę zbudować funkcji do manipulowania zwróconych danych.

-1
tdammon 8 październik 2020, 19:03

1 odpowiedź

Najlepsza odpowiedź

Możesz usunąć se.id z klauzuli GROUP BY i użyj STRING_AGG(), aby wygenerować ciąg CSV:

SELECT vt.user_id, vt.style, vt.environment, STRING_AGG(se.value, ', ') se_values
FROM venue_themes vt 
JOIN theme_settings_to_setting_enum ts ON vt.user_id = ts.user_id 
JOIN setting_enum se ON ts.setting_enum_id = se.id 
GROUP BY vt.user_id;

Zakładając, że user_id jest głównym kluczem venue_themes, wystarczy mieć tylko tę kolumnę w klauzuli GROUP BY (inne kolumny tabeli są niezależnie od klucza podstawowego).

Możesz kontrolować kolejność, w której wartości są agregowane w ciągu za pomocą klauzuli ORDER BY:

STRING_AGG(se.value, ', ' ORDER BY se.id) se_values

Jeśli chcesz tablicy zamiast ciągów CSV, użyj ARRAY_AGG():

ARRAY_AGG(se.value, ', ' ORDER BY se.id) se_values
1
GMB 8 październik 2020, 16:05