回答

收藏

SQL Server:如何将多个行值分组到单独的列中?

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

我试图创建一个SELECT查询,使我可以将联系人的多个电话号码合并到单独的列中。
! l. T- b6 Q9 N$ L3 |' {+ _& ~例如,我想要以下内容' o* ]# o# ?! I" }8 ]$ G8 J( D
Email  |  Phone  |  ID  |, J4 V- L6 d4 `5 J6 ?
------------------------|' o6 {. R8 g- d6 J( O
x@x.com| 555-5555| 001  |2 s/ ^4 d4 V' }7 r' ~
x@x.com| 555-5556| 001  |8 D7 ?: N, d6 x2 c/ {1 G6 ~" C
相反是:
4 k- p& j2 o& r9 s/ L& ]Email  |  Phone  |  Phone2  | Phone3 |  ID  |
. c( i' D) W# ]; i/ P5 D6 W& W* M--------------------------------------------|
1 a- t; ?5 t1 cx@x.com| 555-5555| 555-5556 |  NULL  | 001  |
& S+ M$ j6 W: e2 K1 C3 P尽管这可能是不好的做法,但严格来说,我可以将结果导出到CSV,以便将该数据上传到CRM系统,该系统在导入时不允许任何重复。从那以后MIN,我四处张望,似乎找不到与电话号码相关的答案,并且MAX只允许输入两个而已。
7 C, \( f4 _. i- _最复杂的部分是数据库的结构,最有可能涉及复杂的查询。这是到目前为止我尝试过的操作,但是只能获得2个数字,并且我需要其余的列(请记住,我不是SQL专家):
  K8 J$ I9 Z- Y' W# oSELECT DISTINCT
) }. ?* h9 G( I8 w! J- W' D- i6 v       C.CONTACTID,
' K0 k7 P5 K% _2 v% J       MAX(T.NUMBERVALUE) AS Phone1,
; s+ m! n: ~$ u. |& `' S       MIN(T.numbervalue) AS Phone2
; k- H0 o8 d2 _% x! V" W1 GFROM TBL_PHONE T
0 V5 _$ |7 V) r! J! d) Y     JOIN TBL_CONTACT C ON C.CONTACTID = T.CONTACTID- ~( a$ G/ p/ B3 m* S# Z
     JOIN TBL_EMAIL E ON E.CONTACTID = C.CONTACTID
; U/ @$ j6 y3 nWHERE T.NUMBERVALUE IS NOT NULL
1 u" ~. t/ e1 N  v* N5 V5 z      AND LEN(T.NUMBERVALUE) > 02 c2 E" s/ L" }! u2 D6 @
GROUP BY C.CONTACTID;
2 C) J7 x8 o- `7 ~               
) G! q- ~% }8 V* F2 _) T4 Q: W解决方案:( k8 d" R. \3 n
                + I1 K1 G6 {. _8 Q) F) U
: ^, L( O' A* t' B# z- H6 U; e6 P
! D. Q& a, ~" U7 z" G- f! t& A) W  S
                这是一种动态枢轴方法:+ w  [4 r$ c2 U! r( x/ m
declare @table table (Email varchar(64), Phone varchar(16), ID varchar(3))
6 J$ U; `% d2 m! N" B# D: iinsert into @table
5 T" Q2 ^" a, j% o! S4 H7 ovalues9 y* H) }$ i1 q0 H, J
('x@x.com','555-5555','001'),7 g! i( T" ?6 k' ~
('x@x.com','555-5556','001'),
+ c& L2 I% T+ k9 C) J+ {9 ~0 `) t('x@x.com','555-5557','001'),, m, j* s- X& A& Y. B2 B
('x@x.com','555-5558','001'),
) S* K$ c: [$ w('x@xdd.com','333-5556','002'),% {( G) y. W% D( b9 n
('x@xdd.com','444-5556','002'),
1 t! Q; t6 D; X! U$ S('x@xdd.com','777-5556','002')$ c- e* d1 o- A) e

8 D2 g2 r7 p) a3 x: Y: m- N7 Qselect  J! }" q) F, n
    Email. ]7 j! r) [$ t4 r2 V9 j3 M
    ,Phone) m, ^% K, G/ L7 ]5 @; U
    ,ID- Q! q1 a; \  B& q
    ,row_number() over (partition by ID order by Phone) as RN; J- }  j/ F% n0 r3 }9 _$ y
into #staging: w& z1 ]4 X3 y/ W( u: h
from " W# p0 V* [1 }8 I: l& L3 _
    @table0 X- N, m. G5 h7 Y% s
+ q% d; c8 c7 M/ k" p" w- F

! @6 v2 x, @# d- e# |3 ^7 W8 BDECLARE @DynamicPivotQuery AS NVARCHAR(MAX), \) V; C, T6 T, A1 H5 w
DECLARE @ColumnName AS NVARCHAR(MAX)
; G  t4 P  x1 o- p; O2 i' c% d--Get distinct values of the PIVOT Column
# q, l; W2 r* g; o8 |6 vSELECT @ColumnName= ISNULL(@ColumnName + ',','') 1 ?* B2 @2 A8 j6 x' I0 P+ L& I
       + QUOTENAME(RN): d2 {# \8 W" O) Q/ y+ K
FROM (SELECT DISTINCT RN FROM #staging) AS RN
2 {( R. O: e- ]  _, b--Prepare the PIVOT query using the dynamic
, K4 C4 O2 v+ BSET @DynamicPivotQuery =
9 }: F" Z2 f4 q, X  N'SELECT Email, ID, ' + @ColumnName + '3 q* J% B  |" U6 t
    FROM #staging
; e  A: Y. f9 y& }) F    PIVOT(MAX(Phone) * v4 v2 s# v) E6 a; O
          FOR RN IN (' + @ColumnName + ')) AS PVTTable'5 {0 ~# L; p; M' E: S& Y5 ~% \
--Execute the Dynamic Pivot Query8 P; b# _5 S# I
EXEC sp_executesql @DynamicPivotQuery
  o, D. L) Y1 Zdrop table #staging# Q, N- S+ x# t& I& k5 q0 U3 |
如前所述,如果您只期望3,则可以跳过动态…
  E7 f" y  X0 i6 Bdeclare @table table (Email varchar(64), Phone varchar(16), ID varchar(3))
- Y2 i) O- B% y$ g" C" y) _insert into @table
. y/ M# T; o; Evalues
1 ?& [' ^' V1 b) E('x@x.com','555-5555','001'),0 N7 a1 S3 Q, ^8 W7 k, P; g
('x@x.com','555-5556','001'),3 t2 n. M3 j% U6 H1 R% p9 p1 x+ ~
('x@xdd.com','333-5556','002'),: `* c2 g, Q( v: m) n) k
('x@xdd.com','444-5556','002'),/ X$ t: X7 G% G4 M1 a
('x@xdd.com','777-5556','002')
6 I" H: ~! q- Z$ d; F: l. d. l;with cte as(! U( Y. b+ H0 I7 h# F
select
) h2 I: }5 B* t6 Y    Email
& v& u7 S% V6 r3 C, S$ S+ ~: E    ,Phone
2 a; n  r+ E6 K( }- e9 F! @, }    ,ID$ J1 C- j+ T- q! h. S4 E$ T! r) {
    ,row_number() over (partition by ID order by Phone) as RN
) Z7 l; J( @% ]5 N; }. p. `! ffrom 1 A& S6 s7 n" D6 Q9 k
    @table)1 T, g/ q: ^% L# S
select
4 {! {& [, X2 J9 g- L& o# ^    Email
9 s; {+ t; W- B. U9 A4 I! ^; J    ,max(case when RN = 1 then Phone end) as Phone1
- f, @0 J; J6 d; D, r# C    ,max(case when RN = 2 then Phone end) as Phone2  u9 A4 D& N* O! B
    ,max(case when RN = 3 then Phone end) as Phone3" a- u% \9 ]; U2 i# |1 z" y
    ,ID
+ F+ F8 i$ f, ^1 S+ s5 Nfrom
. v6 k2 T6 o7 j1 r    cte+ K7 F! P# v$ Q
group by
& c0 S& _  X2 \    Email1 Y5 o( o: r3 k0 C; o5 B
    ,ID
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则