您好,我需要在列中添加“R”类型的前 6 件商品和任何其他类型的前 3 件商品的日期和金额。以字母“a”开头的列来自不同的聚合列。 我设法按照下面的代码做到这一点,但是有没有更简单和最佳的方法?我的代码查询源表中需要旋转的每一列,这是两次。
Create Table #TmpChgs (dPer VarChar(25)
,dAmnt Money
,sFlag VarChar(20)
)
Insert Into #TmpChgs
Select '2408.Aug-24',0, 'R'
Union all
Select '2407.Jul-24',188, 'R'
Union all
Select '2401.Jan-24',250, 'R'
Union all
Select '2406.Jun-24',325, 'R'
Union all
Select '2405.May-24',118, 'R'
Union all
Select '2404.Apr-24',0, 'R'
Union all
Select '2403.Mar-24',0, 'R'
Union all
Select '2402.Feb-24',175, 'R'
Union all
Select '2312.Dec-23',0, 'R'
Union all
Select '2311.Nov-22',480, 'R'
Union all
Select '2310.Oct-23',114, 'R'
Union all
Select '2408.Aug-24',0, 'M'
Union all
Select '2407.Jul-24',188, 'M'
Union all
Select '2401.Jan-24',250, 'M'
Union all
Select '2406.Jun-24',325, 'C'
Union all
Select '2405.May-24',118, 'C'
Union all
Select '2404.Apr-24',0, 'M'
Union all
Select '2403.Mar-24',0, 'C'
Union all
Select '2402.Feb-24',175, 'M'
Union all
Select '2312.Dec-23',0, 'C'
Union all
Select '2311.Nov-22',480, 'C'
Union all
Select '2310.Oct-23',114, 'C'
/* Select top 6 R items non 0 order by period and top 3 M or C items non 0 of second type*/
Select Isnull(dt.sType,a.sType) rtype, R1,R2,R3,R4,R5,R6,aR1,aR2,aR3,aR4,aR5,aR6,O1,O2,O3,aO1,aO2,aO3
From
(
Select sFlag As sType
,[R1],[R2],[R3],[R4],[R5],[R6],[O1],[O2],[O3]
FROM (
Select Case When sFlag='R' Then 'R' Else 'O' End + Cast(ROW_NUMBER() OVER(Partition By sFlag Order By dPer desc) as VarChar(10)) As sPer
,dPer
,sFlag
From #TmpChgs
Where dAmnt>0
) As pdt
PIVOT
( Max(dPer) FOR sPer IN ([R1],[R2],[R3],[R4],[R5],[R6],[O1],[O2],[O3])
) as dtPvt
) as dt
Full Outer Join
(Select sFlag As sType
,[aR1],[aR2],[aR3],[aR4],[aR5],[aR6],[aO1],[aO2],[aO3]
FROM (
Select Case When sFlag='R' Then 'aR' Else 'aO' End + Cast(ROW_NUMBER() OVER(Partition By sFlag Order By dPer desc) as VarChar(10)) As sPer
,dAmnt
,sFlag
From #TmpChgs
Where dAmnt>0
) As pdt
PIVOT
( Sum(dAmnt) FOR sPer IN ([aR1],[aR2],[aR3],[aR4],[aR5],[aR6],[aO1],[aO2],[aO3])
) as aPvt
) as A On dt.sType=A.sType
结果看起来不错,但我担心此查询针对日期量较大的表运行时的性能。
r类型 | R1 | R2 | R3 | R4 | R5 | R6 | aR1 | aR2 | aR3 | aR4 | aR5 | aR6 | O1 | 氧气 | O3 | aO1 | aO2 | aO3 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
C | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 2406.6月24日 | 2405.5月24日 | 2311.11 月 22 日 | 325.00 | 118.00 | 480.00 |
M | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 2407.7 月 24 日 | 2402.2 月 24 日 | 2401.1月24日 | 188.00 | 175.00 | 250.00 |
R | 2407.7 月 24 日 | 2406.6月24日 | 2405.5月24日 | 2402.2 月 24 日 | 2401.1月24日 | 2311.11 月 22 日 | 188.00 | 325.00 | 118.00 | 175.00 | 250.00 | 480.00 | 空 | 空 | 空 | 空 | 空 | 空 |
您可以使用条件 case 表达式来执行所需的旋转。
with cte as
(
Select sFlag,
rn = ROW_NUMBER() OVER(Partition By sFlag Order By dPer desc),
dPer,
dAmnt
From #TmpChgs
Where dAmnt > 0
)
select rtype = sFlag,
R1 = max(case when sFlag = 'R' and rn = 1 then dPer end),
R2 = max(case when sFlag = 'R' and rn = 2 then dPer end),
R3 = max(case when sFlag = 'R' and rn = 3 then dPer end),
R4 = max(case when sFlag = 'R' and rn = 4 then dPer end),
R5 = max(case when sFlag = 'R' and rn = 5 then dPer end),
R6 = max(case when sFlag = 'R' and rn = 6 then dPer end),
aR1 = max(case when sFlag = 'R' and rn = 1 then dAmnt end),
aR2 = max(case when sFlag = 'R' and rn = 2 then dAmnt end),
aR3 = max(case when sFlag = 'R' and rn = 3 then dAmnt end),
aR4 = max(case when sFlag = 'R' and rn = 4 then dAmnt end),
aR5 = max(case when sFlag = 'R' and rn = 5 then dAmnt end),
aR6 = max(case when sFlag = 'R' and rn = 6 then dAmnt end),
O1 = max(case when sFlag <> 'R' and rn = 1 then dPer end),
O2 = max(case when sFlag <> 'R' and rn = 2 then dPer end),
O3 = max(case when sFlag <> 'R' and rn = 3 then dPer end),
aO1 = max(case when sFlag <> 'R' and rn = 1 then dAmnt end),
aO2 = max(case when sFlag <> 'R' and rn = 2 then dAmnt end),
aO3 = max(case when sFlag <> 'R' and rn = 3 then dAmnt end)
from cte
group by sFlag