|
我有两个表命名PRODUCT和DETAIL @/ m2 l, ?. H+ e
TABLE: PRODUCT
3 E: ~+ s* l' D' |' Z f" gslno product' e8 r; w6 @6 c5 w+ C7 {0 k1 c, }
1 x * Z) v& S/ H& c
2 y- Q$ F# b4 x/ ^/ V
3 z
- U) F( r# G4 }+ H) rTABLE: DETAIL" f. ^/ [5 F8 L7 q! u% v- J
product detail8 N" s' X' k+ p# j
x good
1 S5 X0 d3 o k/ Oy bad8 O/ u. ]8 J) H [
z worse0 D$ J2 \. W+ ]( T
x bad
, {: ~) \0 @( e. s+ j我需要获得输出
4 K4 Q( I/ C% p* Y1 B. m9 WTABLE
* E, j& |! _2 l) X9 p/ eX Y Z
2 G& @# v: v- egood bad worse
3 g. S2 u# T7 y3 s: gbad
$ t- q. k7 F4 v0 y& v! p. ^ $ C/ C1 x- [4 A8 F2 q
解决方案:4 D6 c4 n2 t" v
+ r0 U% f6 Q* R( X% {% O
& p5 ?- ?- x; N% U# M" o" ~) w- i) L0 q& ]
此数据转换称为A PIVOT,从SQL Server 2005开始,具有将数据从行转换为列的功能。% |. }0 x% C y% m8 d! J
有多种方法可以完成此操作,具体取决于您是否有要转换为列的静态数量的值。所有这些都涉及向row_number()数据添加a
5 u: u- e6 s6 D2 Z" R" h" T,因此您可以返回任何产品的多行。
# y; J# m0 A$ V您可以将聚合函数与CASE表达式一起使用:1 F' T. W$ `# Y) m8 ?8 @
select 8 M. D$ F3 I& @: n& Z; ?
max(case when product = 'x' then detail end) x,+ L+ ^: f y- c6 u1 g( ?
max(case when product = 'y' then detail end) y,
4 k, b; w8 c; g% ^4 C8 A max(case when product = 'z' then detail end) z
! ]9 ]# L% d1 m) ]" F0 nfrom
+ c! G6 I: i- a E# J1 N(3 ?: ^5 V$ y" U7 ?% s. l
select p.product, d.detail,
. s/ n8 D/ g- V row_number() over(partition by p.product order by p.slno) rn; o7 Z8 B6 ~/ s" b- f# ~
from product p
' Y3 q& y% B# p inner join detail d- h& `4 i, Q3 P: O
on p.product = d.product
9 E& G# @0 W( o/ r+ I& b) src8 T- `# z( l- D2 B
group by rn
( N; r# j# n$ x# B参见带有演示的SQL Fiddle- J9 P5 C& o9 r5 i& s
您可以使用以下PIVOT功能:
$ V: m1 R+ J4 Yselect x, y, z
) _% r/ M0 ~( z" V$ n: d9 Tfrom" O# N- Z* F! c+ X ?# m6 p
(
6 G' t/ x0 h; g7 Z2 V* P- i- A' i select p.product, d.detail," h' ?: S b% ?1 ~; o
row_number() over(partition by p.product order by p.slno) rn
2 p0 G- u; Z* R+ f/ K7 ?. C from product p# f D& o* j% N2 \+ S5 A
inner join detail d
M. }* N; F9 E3 i) j2 i. g on p.product = d.product' z: t, g7 }+ o1 Y
) src
7 U* p1 ` k% f3 Q/ Wpivot2 y" T; M4 K& C- O; Y7 Q
(# I$ I0 C+ H. |% @/ T
max(detail)5 i) c6 Q( Q8 I: r' p
for product in (x, y, z)/ G( e& Q. r `5 E% }& p1 E
) piv9 [# k6 q( G1 `0 z, Y
请参阅带有演示的SQL Fiddle。/ l3 j! F4 |1 M
如果您有未知数量的值(在这种情况下为产品)要转换为列,那么您将要使用动态SQL:
* x: R; ]" r# h9 eDECLARE @cols AS NVARCHAR(MAX),2 ^ R) e3 t! K ]
@query AS NVARCHAR(MAX)9 n# }0 I( t# i
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(product)
7 I5 T U( F; v from product1 s/ X, w2 t6 t
FOR XML PATH(''), TYPE
/ }& P* g2 d% ` A ).value('.', 'NVARCHAR(MAX)')
$ }1 z7 V8 P# e7 S6 F1 g: s: G4 [) u ,1,1,'') S4 _/ P+ {4 l i( P: Z
set @query = 'SELECT ' + @cols + ' from
6 u4 Q9 F) I* @& K (
. V, N. w+ s4 c% g1 J select p.product, d.detail,' Y& \. Z" A/ E3 D% F$ ? J
row_number() over(partition by p.product order by p.slno) rn
" g- T) ?- F3 v" E! t; p from product p
% H( p" A7 D- `2 ` inner join detail d
0 G+ N2 R& ^! ^. R: d( ?% ` on p.product = d.product2 `- k) A2 L2 R
) x
/ u( }3 N' g' z3 F6 ^, { pivot
1 E7 l# s: h' O" ]. L6 V5 T8 X* O ] (
9 k a$ {! t% N8 [! x/ V. C1 d max(detail)! D2 d3 p- R$ M9 c$ N( X2 \! p
for product in (' + @cols + ')0 [ P: z. L) d+ \/ h) \* o
) p '0 J( p& ^& D) j! p) k: j
execute(@query)! s- ?6 T# r+ L& I
参见带有演示的SQL Fiddle
- S, r! E' T" G% J8 d9 D. l所有查询的结果是:8 d- e8 u$ X& P
| X | Y | Z |6 a4 r$ j h* @$ A1 E1 e
--------------------------
4 ^! `) p$ ?' W* G" H| good | bad | worse |2 z( J" \, J; W) l+ { `
| bad | (null) | (null) | |
|