2017-02-03 46 views
3

我想将多个表连接在一起。我试图加入的其中一个表每个数据ID有数百行。我试图将每个ID的约100行转为列。我尝试使用的值并不总是在同一行中。下面是一个例子(我的真实表格每个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分钟内完成线。然而,问题在于,只从我指定的列中提取值,所以我将一直丢失不同列中的数据。 (在上面的例子中,我会得到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 

等等...

然后我选择我的所有数百行,然后转动它的数据:

from CTE 
pivot (max(Value) for [QType] in ([AccNum],[EmpNam],(more rows)))As c 

但是,这段代码的问题在于它需要运行将近2个小时。

有什么不同的,更有效的解决方案,我想完成什么?我需要有第一个代码的速度,但第二个代码的结果。

+0

大概是(你可以尽管检查)这是一个的服用时间,而不是CTE,但是我希望你可以简化与COALESCE([CharV]热膨胀系数的值=行的支点,[NumV] 0 ),看看是否有任何影响。 – Rikalous

+0

不幸的是,这是行不通的,因为没有任何字段是真正的空值。如果CharV没有值,那么它是一个空字符串“”,如果NumV没有值,它只是0. –

回答

2

也许你可以通过使用UNION ALL

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 

对于条件聚合方法

不用担心减少Concat/NullIf处理哪些领域,只是参考值

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 
+0

对于这种方法,Union All会在CTE内,还是在后面的select语句? –

+0

@VBA_SQL_Programmer我见过性能受到大型CTE的影响。查看这两种方法的更新回答 –

+0

@VBA_SQL_Programmer我没有意识到你正在处理的行有多可能,但是,TEMP表中没有SHAME –