SQL Server - 将多行合并为一行

时间:2011-10-06 09:08:55

标签: sql sql-server

希望你能帮忙...... 我有这种格式的数据表(让我们把这个表称为'产品')

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 productid=@productid and property_name='type';
    select @name=property_value from product where productid=@productid and property_name='name';
    select @cost=property_value from product where productid=@productid 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

较慢的响应可能会降至'distinct',但如果没有,我会得到重复的记录。我很感激任何建议,以获得更快的SQL响应。

非常感谢

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可以通过将表重新连接到自身几次来实现这一点,但可能会出现一些性能问题。

答案 2 :(得分: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