更有效地旋转行
more efficiently pivot rows
我正在尝试将多个 table 连接在一起。我尝试加入的 table 之一每个数据 ID 都有数百行。我正在尝试将每个 ID 的大约 100 行转换为列。我尝试使用的值并不总是在同一行中。下面是一个示例(我的真实 table 每个 ID 有数百行)。例如,ID 1 中的 AccNum 可能在 NumV 列中,但对于 ID 2,它可能在 CharV 列中。
ID QType CharV NumV
1 AccNum 10
1 EmpNam John Inc 0
1 UW Josh 0
2 AccNum 11
2 EmpNam CBS 0
2 UW Dan 0
我使用的原始代码是一个 select 语句,有数百行,如下所示:
Max(Case When PM.[QType] = 'AccNum' Then NumV End) as AccNum
这段代码有数百行,仅用了不到 10 分钟的时间就完成了。然而,问题是 in 只从我指定的列中提取值,所以我总是会丢失不同列中的数据。 (在上面的示例中,我会得到 AccNum 10,但不是 AccNum11,因为它在 CharV 列中)。
我更新了代码以使用数据透视表:
;with CTE
As
(
Select [PMID], [QType],
Value=concat(Nullif([CharV],''''),Nullif([NumV],0))
From [DBase].[dbo].[PM]
)
Select C.[ID] AS M_ID
,Max(c.[AccNum]) As AcctNum
,Max(c.[EmpNam]) As EmpName
等等...
然后我 select 我的所有数百行然后将数据旋转它:
from CTE
pivot (max(Value) for [QType] in ([AccNum],[EmpNam],(more rows)))As c
但是,此代码的问题在于 运行。
需要将近 2 个小时
是否有不同的、更有效的解决方案来解决我想要完成的任务?我需要第一个代码的速度,但是第二个代码的结果。
也许您可以使用 UNION ALL
来减少 Concat/NullIf
处理
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
对于条件聚合方法
不用管是哪个字段,只要引用VALUE
Select [ID]
,[Accnum] = Max(Case When [QType] = 'AccNum' Then Value End)
,[EmpNam] = Max(Case When [QType] = 'EmpNam' Then Value End)
,[UW] = Max(Case When [QType] = 'UW' Then Value End)
From (
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
) A
Group By ID
对于 PIVOT 方法
Select [ID],[AccNum],[EmpNam],[UW]
From (
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
) A
Pivot (max([Value]) For [QType] in ([AccNum],[EmpNam],[UW])) p
我正在尝试将多个 table 连接在一起。我尝试加入的 table 之一每个数据 ID 都有数百行。我正在尝试将每个 ID 的大约 100 行转换为列。我尝试使用的值并不总是在同一行中。下面是一个示例(我的真实 table 每个 ID 有数百行)。例如,ID 1 中的 AccNum 可能在 NumV 列中,但对于 ID 2,它可能在 CharV 列中。
ID QType CharV NumV
1 AccNum 10
1 EmpNam John Inc 0
1 UW Josh 0
2 AccNum 11
2 EmpNam CBS 0
2 UW Dan 0
我使用的原始代码是一个 select 语句,有数百行,如下所示:
Max(Case When PM.[QType] = 'AccNum' Then NumV End) as AccNum
这段代码有数百行,仅用了不到 10 分钟的时间就完成了。然而,问题是 in 只从我指定的列中提取值,所以我总是会丢失不同列中的数据。 (在上面的示例中,我会得到 AccNum 10,但不是 AccNum11,因为它在 CharV 列中)。
我更新了代码以使用数据透视表:
;with CTE
As
(
Select [PMID], [QType],
Value=concat(Nullif([CharV],''''),Nullif([NumV],0))
From [DBase].[dbo].[PM]
)
Select C.[ID] AS M_ID
,Max(c.[AccNum]) As AcctNum
,Max(c.[EmpNam]) As EmpName
等等...
然后我 select 我的所有数百行然后将数据旋转它:
from CTE
pivot (max(Value) for [QType] in ([AccNum],[EmpNam],(more rows)))As c
但是,此代码的问题在于 运行。
需要将近 2 个小时是否有不同的、更有效的解决方案来解决我想要完成的任务?我需要第一个代码的速度,但是第二个代码的结果。
也许您可以使用 UNION ALL
Concat/NullIf
处理
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
对于条件聚合方法
不用管是哪个字段,只要引用VALUE
Select [ID]
,[Accnum] = Max(Case When [QType] = 'AccNum' Then Value End)
,[EmpNam] = Max(Case When [QType] = 'EmpNam' Then Value End)
,[UW] = Max(Case When [QType] = 'UW' Then Value End)
From (
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
) A
Group By ID
对于 PIVOT 方法
Select [ID],[AccNum],[EmpNam],[UW]
From (
Select ID,QType,Value=CharV From @YourTable where CharV>''
Union All
Select ID,QType,Value=cast(NumV as varchar(25)) From @YourTable where NumV>0
) A
Pivot (max([Value]) For [QType] in ([AccNum],[EmpNam],[UW])) p