PostgreSQL 从多对多关系中将数据作为数组返回
PostgreSQL returning data as an array from a many to many relationship
我正在寻找存储和检索数据数组的最佳方式。我目前正在实施的解决方案使用如下多对多关系。
venue_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
setting_enum
id value
1 garden
2 beach
3 golf course
4 backyard
我目前的查询是:
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;
这有效,但它 return 多行具有与我设置的枚举值不同的相同数据。
一个例子 return 是:
user_id style environment value
AAAA formal indoor beach
AAAA formal indoor backyard
AAAA formal indoor tent
这很好,但如果我有很多值,这似乎太过分了。我真正希望我的数据看起来像:
user_id style environment value
AAAA formal indoor beach, backyard, tent
理想情况下,我会将我的值 returned 放入数组或类似的东西中,这样我就不必构建函数来操作 returned 数据。
您可以从 GROUP BY
子句中删除 se.id
,并使用 STRING_AGG()
生成 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;
假设user_id
是venue_themes
的主键,在GROUP BY
子句中只有这一列就足够了(table的其他列是功能上依赖于主键)。
您可以使用 ORDER BY
子句控制值在字符串中的聚合顺序:
STRING_AGG(se.value, ', ' ORDER BY se.id) se_values
如果您想要一个数组而不是 CSV 字符串,请使用 ARRAY_AGG()
:
ARRAY_AGG(se.value, ', ' ORDER BY se.id) se_values
我正在寻找存储和检索数据数组的最佳方式。我目前正在实施的解决方案使用如下多对多关系。
venue_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
setting_enum
id value
1 garden
2 beach
3 golf course
4 backyard
我目前的查询是:
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;
这有效,但它 return 多行具有与我设置的枚举值不同的相同数据。
一个例子 return 是:
user_id style environment value
AAAA formal indoor beach
AAAA formal indoor backyard
AAAA formal indoor tent
这很好,但如果我有很多值,这似乎太过分了。我真正希望我的数据看起来像:
user_id style environment value
AAAA formal indoor beach, backyard, tent
理想情况下,我会将我的值 returned 放入数组或类似的东西中,这样我就不必构建函数来操作 returned 数据。
您可以从 GROUP BY
子句中删除 se.id
,并使用 STRING_AGG()
生成 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;
假设user_id
是venue_themes
的主键,在GROUP BY
子句中只有这一列就足够了(table的其他列是功能上依赖于主键)。
您可以使用 ORDER BY
子句控制值在字符串中的聚合顺序:
STRING_AGG(se.value, ', ' ORDER BY se.id) se_values
如果您想要一个数组而不是 CSV 字符串,请使用 ARRAY_AGG()
:
ARRAY_AGG(se.value, ', ' ORDER BY se.id) se_values