2011-10-06 49 views
1

希望你能帮助... 我有数据表格式(让参照此表作为“产品”)SQL服务器 - 多行成一个

productid property_name property_value last_updated 
p0001   type  p1    05-Oct-2010 
p0001   name  Premium   05-Oct-2010 
p0001   cost  172.00   05-Oct-2010 
p0002   type  p3    06-Oct-2010 
p0002   name  standard  06-Oct-2010 
p0002   cost  13.00   06-Oct-2010 

*(there are like 50 more properties of which i would need 15 atleast in my query. 
However, i just ignore them for this example)* 

我需要在这个格式的数据:

productid  type  name   cost 
p0001   p1   Premium  172.00 
p0002   p3   standard 13.00 

我试着用一个函数和视图来获得这种格式,但它需要好几分钟才能获得1000条记录。想知道如果有人知道更快的方式?

我试了一下:

Create function fun1(@productid nvarchar(50)) returns @retdetails table 
(
type nvarchar(50) null, 
name nvarchar(50) null, 
cost nvarchar(50) null, 
) 
begin 
declare 
    @type nvarchar(50), 
    @name nvarchar(50), 
    @cost nvarchar(50), 

    select @type=property_value from product where [email protected] and property_name='type'; 
    select @name=property_value from product where [email protected] and property_name='name'; 
    select @cost=property_value from product where [email protected] and property_name='cost'; 

    if isnull(@productid,'')<>'' 
    begin 
     insert @retdetails 
      select @type, @name, @cost; 
    end; 
    return; 
end; 

然后视图

select p.productid, pd.type, pd.name, pd.cost 
from (select distinct productid from product) p 
cross apply dbo.fun1(p.productid) pd 

较慢的响应可能会下调至“独立的”,但没有,我得到重复的记录。我将不胜感激任何建议,以获得更快的SQL响应。

非常感谢

+0

正在改变表结构的选项呢? – Purplegoldfish

+0

谢谢你的快速回复。我没有自己的表和其刷新的一些外部对象,所以不能改变表(不知道为什么它被设计在第一个地方,可能是为了方便添加新的属性)。尝试自我加入,超过15个属性。由于波格丹,我去了更容易的选择(我不明白枢轴:))) – user981785

回答

1

你可以试试这个PIVOT方法

SELECT productid, 
     MAX(CASE WHEN property_name = 'type' THEN property_value END) AS type, 
     MAX(CASE WHEN property_name = 'name' THEN property_value END) AS name, 
     MAX(CASE WHEN property_name = 'cost' THEN property_value END) AS cost 
FROM Product 
GROUP BY productid 
+0

非常感谢马丁。你的查询像宝石一样工作。在不到4秒的时间内完成所有15个属性和约1000条记录。我浪费了几个小时在这个,你简单的:) – user981785

0

您可以通过参加表回到自身上几次可能做到这一点,可能会有点性能问题虽然。

+0

如果你仔细看看这个问题,但是[根据索引实际上可能比'PIVOT'更有效](http:// stackoverflow。 com/questions/7448453/sql-server-pivot-vs-multiple-join/7449213#7449213) –

+0

我撇去那个部分,以为他说过50多行不是属性,但他只需要15个! – Purplegoldfish

0

SQL Server 2005开始,你可以使用PIVOT操作:

DECLARE @TestData TABLE 
(
    productid  VARCHAR(5) NOT NULL 
    ,property_name VARCHAR(5) NOT NULL 
    ,property_value VARCHAR(10)NOT NULL 
    ,last_updated DATETIME NOT NULL 
); 
INSERT @TestData 
SELECT 'p0001','type','p1'  ,'05-Oct-2010' 
UNION ALL 
SELECT 'p0001','name','Premium' ,'05-Oct-2010' 
UNION ALL 
SELECT 'p0001','cost','172.00' ,'05-Oct-2010' 
UNION ALL 
SELECT 'p0002','type','p3'  ,'06-Oct-2010' 
UNION ALL 
SELECT 'p0002','name','standard','06-Oct-2010' 
UNION ALL 
SELECT 'p0002','cost','13.00' ,'06-Oct-2010'; 

;WITH PivotSource 
AS 
(
    SELECT a.productid 
      ,a.property_name 
      ,a.property_value 
    FROM @TestData a 
) 
SELECT pvt.* 
     --,CONVERT(NUMERIC(8,2), pvt.cost) NumericCost 
FROM PivotSource src 
PIVOT (MAX(src.property_value) FOR src.property_name IN ([type], [name], [cost])) pvt 

结果:

productid type name cost NumericCost 
p0001 p1 Premium 172.00 172.00 
p0002 p3 standard13.00 13.00