回答

收藏

PostgreSQL:将与数组的关系展平,以使每个数组条目发出一行

技术问答 技术问答 233 人阅读 | 0 人回复 | 2023-09-13

给定这样定义的表:& z* w/ ~( O/ ]: B4 M7 [
CREATE TABLE test_values(name TEXT, values INTEGER[]);& W, {3 P4 l  L. c( n
…以及以下值:. U/ S8 H" [8 x0 s$ N
| name  | values  |3 M$ P& N8 u* A7 q2 l
+-------+---------+
. y: z$ y/ F* U! N! M; f| hello | {1,2,3} |+ O0 D! h5 y$ j) }  @
| world | {4,5,6} |
7 Y! v6 I: L/ o2 H. b我试图找到一个查询,该查询将返回:
8 z! _+ S( L# ~| name  | value |
7 u& m, m( Z' M' P8 \$ t1 T7 C+-------+-------+
0 N- H9 {' h( M; M| hello | 1     |
. s  Y' W; K/ g6 W| hello | 2     |
5 J6 g  |" O& F" ?* H, x$ [) i. `| hello | 3     |! e* k9 Y2 L, c
| world | 4     |
. D- F' Y. q! Q( B/ G+ ]| world | 5     |
2 ~$ ]" `4 ]( E6 q, r( N% Y/ A| world | 6     |
& d% s; v2 q& K# ~" ]我已经阅读了有关访问数组的上游文档,并试图考虑使用该unnest()函数的解决方案是什么样的,但是一直空无一人。: F  A: ?9 @! s' f$ x2 S) c) N
理想的解决方案即使在扩展数组而不是主键且没有大量列的情况下,也易于使用。处理具有多个数组的案例并不重要。7 S8 a) c* y$ G; J
                9 G3 |9 H7 }0 Y2 f8 X
解决方案:
* f: w4 k' ]7 z) [               
, h5 ~0 V$ r# ]& ]$ L
, S0 w3 E6 L, O/ F( U7 X- ]3 w* `( |/ z0 r6 S- t
                您可以像Rapha毛l建议的那样将返回集合的函数unnest()放入SELECT列表中。但是在Postgres9.3或更高版本中,请为此使用联接。这是将集合返回函数放入列表而不是列表的更干净,更可取的,符合标准的方法LATERALFROM``SELECT
: @6 F- Z% o5 H. ySELECT name, value. R4 Y- R5 q, _
FROM   tbl, unnest(values) value;  -- implicit CROSS JOIN LATERAL
7 Q: n1 h( ]! J0 [# d& z一个微妙的区别:values由于 没有unnest()返回 row ,因此从结果中删除具有空/ NULL的 行( ]/ p' h7 K9 `
,而在FROM列表中将相同的 行 转换为NULL值并始终返回。100%等效查询为:
+ i1 h$ H7 W  a7 sSELECT t.name, v.value& b& @! d# u- D/ C
FROM   tbl t
% J: ]5 P/ ^" Y# XLEFT   JOIN unnest(t.values) v(value) ON true;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则