|
请帮我这个:
5 L. f1 v1 l' Q _: H1 o我想按列TestType分组,但如果它们具有相同的TestType,则应将Result拆分为colunms
# U) D2 p/ `& f8 J5 [CREATE TABLE Result(WorkOrder varchar(10), TestType varchar(20), Result decimal(10,2));7 l5 ]+ p1 V3 u7 Q/ q+ W
INSERT INTO Result (WorkOrder, TestType, Result) VALUES % N: c; F2 ?* C' ~4 @$ g, F% {
('HP19002316','VitaminA', 10.3),( d7 k; P! ?) M0 v% K* m
('HP19002316','VitaminA', 11.3),
) i5 t( i: I$ z9 M('HP19002316','VitaminA', 12.3),9 y: S- l, J" J) p: e; P* S( G1 {; K
('HP19002316','VitaminB', 13.4),
$ Q; _4 A2 S& C' r9 X('HP19002316','VitaminB', 14.4),
9 ?/ d4 P$ H" G* t('HP19002316','VitaminC', 15.5),
8 a9 b; u+ `1 R: Q: c) S: i1 e('HP19002316','VitaminD', 17.0)+ d8 W6 v$ j5 b
我希望SQL以这种格式返回数据
5 k8 s* q, M E; ]8 SWorkOrder TestType Result1 Result2 Result3
; O: m' _# |, t==========================================================( D; N1 N' D2 k
HP19002316 VitaminA 10.3 11.3 12.3 ( E$ ~6 W' Z* H4 ~0 j
HP19002316 VitaminB 13.4 14.4 NULL
) u; ^# [: n( S) n; mHP19002316 VitaminC 15.5 NULL NULL7 O L6 y5 W7 w+ B" [1 O; W4 Z
HP19002316 VitaminD 17.0 NULL NULL
) M$ d8 S0 t! ~) z* `, H4 O: _3 a- NResult#列应该是动态的,因为每个TestType都有很多结果
5 S+ B, G1 w/ r' E5 T; P" ]
) ]( {0 Q8 `: U& v- v/ H" L解决方案:1 n2 y( [: e5 v6 h8 G4 C
3 n/ w, n& V- G2 U/ ^
( V/ b. e1 ?) r9 P+ R$ b4 g+ M- L5 s! j
正如我在评论中所提到的,这里您需要的是PIVOT或交叉标签;我更喜欢后者,所以我将要使用的东西。
' H9 ^5 b% R! B9 V+ U5 ^对此的非动态解决方案如下:
& C( I0 r v" M- X: H9 a) b3 x2 \# qWITH RNs AS(
9 \: A/ S3 @7 t* h2 c4 R$ J# d SELECT WorkOrder,! B( r, Q9 [$ U6 I9 {& y* H- v+ u3 J
TestType,: ^9 y2 R" h2 Z5 N
Result,( G( X; g9 w6 s! w% u+ I% d
ROW_NUMBER() OVER (PARTITION BY WorkOrder, TestType ORDER BY (SELECT NULL)) AS RN --ORDER BY should be your ID/always ascending column
1 f/ w; o! Z4 C& D4 S7 f% G FROM dbo.Result)
- H6 d8 d* L/ }2 C+ l7 B, v/ U x. s# ZSELECT WorkOrder,
8 `9 B; ?3 ]: z! K8 b TestType,+ P h- P; s1 C, E% v" h. R+ O
MAX(CASE RN WHEN 1 THEN Result END) AS Result1, u0 K r% L' U7 c1 G! G% U
MAX(CASE RN WHEN 2 THEN Result END) AS Result2,
0 G, X1 {) ?7 r+ P4 m0 Y' f) o MAX(CASE RN WHEN 3 THEN Result END) AS Result3
6 O: b, Y- o" B5 P2 i: SFROM RNs R/ _' s- g6 Q* X$ e
GROUP BY WorkOrder,
1 T2 j, j U+ ]( |2 x TestType;
/ T5 `3 A7 E4 \! M5 f' i但是,问题在于这会将您“锁定”到3个结果中,但是您建议存在不确定数量的结果。因此,您需要一个动态的解决方案。
) C' H; i3 N+ {+ O以下将最多处理100个结果。如果你 需要 更多的列比超过,再加入更多的CROSS JOINs到N的CTE
% T: d4 {* n7 D8 u0 D8 OTally。结果是这样的(非常混乱)。
7 t/ j d( Y5 Q/ G6 j+ ADECLARE @SQL nvarchar(MAX),9 y+ G2 s0 k( h1 ^# ^
@CRLF nchar(2) = NCHAR(13) + NCHAR(10),
2 s8 c3 A9 m& H @MaxTally int;, U3 v4 n4 {/ ^, \" m6 S
SELECT @MaxTally = MAX(C)
8 p2 S/ X' T5 S! w' lFROM (SELECT COUNT(*) AS C! x( x3 o0 C' n E6 x' K
FROM dbo.Result* e: L4 F2 b# I; Y5 P# y
GROUP BY WorkOrder,) N! ?% k0 C/ q9 {9 N
TestType) R;
: `' r) c |! K" [1 G4 Q( y& p) yWITH N AS(4 V7 f( A" V" M4 m7 O; T1 }
SELECT N: {3 Q4 T' a* f& K
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),# ~) ]' r1 M- J5 H, S U
Tally AS(
- u. m8 I9 ?# r( P SELECT TOP (@MaxTally) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
& E, m' ` ^* f9 Q$ L- I FROM N N1, N N2) --100 rows, add more Ns for more rows* x h( x+ N# K* J7 k. n4 Z5 J0 I
SELECT @SQL = N'WITH RNs AS(' + @CRLF +
' c) k8 O A8 S' Y; G. B N' SELECT WorkOrder,' + @CRLF +
3 y; k8 U4 M6 l( ]" q% F7 w Z N' TestType,' + @CRLF +" T' Q5 {2 G% u6 Y. z
N' Result,' + @CRLF +
3 @- S, B4 ?7 ^ N' ROW_NUMBER() OVER (PARTITION BY WorkOrder, TestType ORDER BY (SELECT NULL)) AS RN --ORDER BY should be your ID/always ascending column' + @CRLF +
' I% G) ]- m$ _8 z N' FROM dbo.Result)' + @CRLF +
9 C( g: v$ R5 h5 A$ } N'SELECT WorkOrder,' + @CRLF +
7 d/ o& e# s3 I% p7 m ^- ^ N' TestType,' + @CRLF +
9 `2 }( A: n' ] --Using FOR XML PATH due to not knowing SQL Server version
# Q! r) Y2 b4 D/ C9 x2 t STUFF((SELECT N',' + @CRLF +
& o0 | U D) M- {. b1 l* t; s CONCAT(N' MAX(CASE RN WHEN ',T.I,N' THEN Result END) AS Result',T.I)( v# F; W+ n4 S3 D+ {8 E. X7 I' v
FROM Tally T# m: q% l ~9 I }
ORDER BY T.I ASC
4 c/ H' n: Y$ ]% Q FOR XML PATH(N''),TYPE).value('(./text())[1]','nvarchar(MAX)'),1,3,N'') + @CRLF +
- v, @+ h* Z+ q( n% p N'FROM RNs R' + @CRLF ++ I4 Y$ D5 ^8 @# \9 l# Z
N'GROUP BY WorkOrder,' + @CRLF +
8 O! O6 R" x2 k N' TestType;';
0 S& T! h+ i6 ~$ PPRINT @SQL; --Your best friend.
* J0 M- T; s# y' KEXEC sys.sp_executesql @SQL; |
|