回答

收藏

使用CASE WHEN在postgresql中创建数据透视表的正确方法

技术问答 技术问答 275 人阅读 | 0 人回复 | 2023-09-14

我正在尝试在postgresql中创建数据透视表类型视图,并且快要完成了!这是基本查询:/ r. Y0 T7 J& Y* R" J! }
select 6 W9 p7 p( N, `3 i7 B7 l
acc2tax_node.acc, tax_node.name, tax_node.rank
/ I" A  }# E9 p+ k& E2 f1 o! Zfrom ) P3 e% M/ s8 Y  H, I* d! ~: d
tax_node, acc2tax_node : G$ P* f! [" m5 l0 m
where
, h% B6 X# k7 x; F* btax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531';
9 x7 V+ U  `  S5 ]7 O和数据:
+ C9 v1 s, R: j. y0 n0 [7 I   acc    |          name           |     rank     : j( Q/ v+ m( c# T& H( L+ f7 B
----------+-------------------------+--------------
/ H( _1 L& Y8 i- M. G AJ012531 | Paromalostomum fusculum | species
9 v% e$ l" W8 ]9 i; I( I AJ012531 | Paromalostomum          | genus
4 U6 [% ?7 r! K7 X. N! a9 y1 k AJ012531 | Macrostomidae           | family1 x0 I  H, ~: ]$ y( x9 C4 B0 s
AJ012531 | Macrostomida            | order
- Y# w) b: D5 p8 h1 V1 \ AJ012531 | Macrostomorpha          | no rank
- Z" T  ]( a) y" r% ` AJ012531 | Turbellaria             | class- E, B. v+ N" ^( ^: j; x& |
AJ012531 | Platyhelminthes         | phylum* ^& T0 Q# m- Y- k
AJ012531 | Acoelomata              | no rank3 D# ?8 H* D- l; E1 Y7 W. A
AJ012531 | Bilateria               | no rank
( J5 K0 |" K- e AJ012531 | Eumetazoa               | no rank
3 \3 @1 q% |) u; Y( m) r, M AJ012531 | Metazoa                 | kingdom
( v+ ]1 l* f7 j. X3 U0 M AJ012531 | Fungi/Metazoa group     | no rank5 v" {* n- a& E# A8 G  \( R7 s) l
AJ012531 | Eukaryota               | superkingdom
2 k- q4 C1 \0 P- d0 W; j  } AJ012531 | cellular organisms      | no rank
5 D7 o# k, C3 t! l5 ]2 B我想要得到的是以下内容:- W, i+ L) t& D" h! L
acc      | species                  | phylum+ d- a6 _6 w, J4 E: d4 S
AJ012531 | Paromalostomum fusculum  | Platyhelminthes
5 O: ?/ i! I1 N* e3 _( U我正在尝试使用CASE WHEN进行此操作,因此我得到了以下信息:3 l+ u6 r% Y) d! ?7 H
select
5 m, h" a0 x9 J$ o5 T1 K) _  nacc2tax_node.acc,
# |% Q# w0 g2 i2 G, \1 L4 YCASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END as species,
* n& [+ w% X) R$ z  l2 dCASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END as phylum & k# \- V, p$ ~/ v6 o
from   {: x) G1 O4 K8 Y# \' [+ b6 ^
tax_node, acc2tax_node & n! G, {) ]' Z
where 9 P% K+ z- F: s) ?
tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531';
. [, w+ C2 [5 k& w这给了我输出:
$ [( T. j& }2 j   acc    |         species         |     phylum      , A( [( ^" W7 ~7 p
----------+-------------------------+-----------------
" p5 k/ y/ w6 Z* I AJ012531 | Paromalostomum fusculum | - E- Y6 q9 M& A0 A
AJ012531 |                         |
/ l6 F5 f# Y3 d AJ012531 |                         | " ]5 F3 L6 \0 w
AJ012531 |                         | : }& U! M( P; s' O8 W
AJ012531 |                         |
6 I4 ^$ O4 ?' D" L4 Y8 X( J3 g$ E$ ? AJ012531 |                         | 2 U( H% f$ X+ P7 y  c2 m- Q
AJ012531 |                         | Platyhelminthes' }3 _, \' D1 m. N
AJ012531 |                         |
/ C; n1 U6 W' f5 ^, H AJ012531 |                         | 4 Q- b) v* F( G) z; _: I" A
AJ012531 |                         |
: _3 u% S. [4 ?; _+ z9 r AJ012531 |                         |
! L6 z+ [2 Z0 I$ M3 Z AJ012531 |                         | $ ~( C9 @" X# }  G
AJ012531 |                         |
) i# {2 E5 C; e1 V: _; T/ w AJ012531 |                         |
& F' @# s! m+ a3 t2 a现在我知道我必须在某个时候按acc分组,所以我尝试( E; B* i8 Z- E' m
select
( b  O$ g( s0 j! j; {acc2tax_node.acc, & E, y: i% K- P. P
CASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END as sp,
$ y# X0 z' E8 h2 L% u* JCASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END as ph ! U( f5 I% G# m& J; _
from
$ e$ G! ]- F6 R' i7 t. Etax_node, acc2tax_node
0 q! y4 \2 ]6 G- hwhere
6 I+ S5 x) a5 n' v5 V/ l: k/ ntax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531' ' Y4 ?  F6 {  T5 d8 n
group by acc2tax_node.acc;  w  W% ^9 }2 ?  u
但我感到恐惧
0 W; W# C! k3 T: j/ j% o1 hERROR:  column "tax_node.rank" must appear in the GROUP BY clause or be used in an aggregate function
5 D/ j& t& T, Y9 l0 W- {我能够找到的所有先前示例在CASE语句周围都使用了SUM()之类的东西,所以我想那是聚合函数。我尝试使用FIRST():9 ~2 K5 u6 P( j2 i9 g, ~
select
8 O2 M# z: Q6 U6 Racc2tax_node.acc,
  T8 e3 @4 C* y; i! mFIRST(CASE tax_node.rank WHEN 'species' THEN tax_node.name ELSE NULL END) as sp,
+ p' s! y5 K9 {0 e4 C% oFIRST(CASE tax_node.rank WHEN 'phylum' THEN tax_node.name ELSE NULL END) as ph ! G$ B  M1 m* y2 i
from tax_node, acc2tax_node where tax_node.taxid=acc2tax_node.taxid and acc2tax_node.acc='AJ012531' group by acc2tax_node.acc;9 M8 u3 L: c, K7 P
但得到错误:
9 |. H$ m. [8 b7 P9 iERROR:  function first(character varying) does not exist
# i+ i4 i: R; o) P$ D谁能提供任何提示?* |6 S+ g7 ?3 U9 a
                ' P# G+ U) ~0 |4 M: |5 W- D  R* c
解决方案:0 I$ S% t1 y: X* `8 D$ z
               
1 z, x/ |- h; P. J" x, V; W) ^' ~) p! u/ }# Q

4 [9 L6 S* S7 ^# `% a                使用MAX()或MIN(),而不是FIRST()。在这种情况下,每个组值在列中将具有所有NULL,但最多只有一个不为null的值。根据定义,这是该组值的MIN和MAX(排除所有空值)。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则