使用单个表将数据行转换为列的SQL

使用单个表将数据行转换为列的SQL,sql,sql-server-2008,database-performance,Sql,Sql Server 2008,Database Performance,我正在尝试将DB表中的一行转换为列,并使用带游标的PIVOT函数,下面是Sql: DECLARE Cur CURSOR FOR SELECT DISTINCT CounterId FROM AllCounterIds DECLARE @Temp NVARCHAR(MAX), @AllCounterIds NVARCHAR(MAX), @CounterIdQuery NVARCHAR(MAX) SET @AllCounterIds = '' OPEN Cur -- Getti

我正在尝试将DB表中的一行转换为列,并使用带游标的PIVOT函数,下面是Sql:

DECLARE Cur CURSOR FOR
  SELECT DISTINCT CounterId
  FROM AllCounterIds

DECLARE @Temp NVARCHAR(MAX),
  @AllCounterIds NVARCHAR(MAX),
  @CounterIdQuery NVARCHAR(MAX)

SET @AllCounterIds = ''

OPEN Cur
-- Getting all the movies
FETCH NEXT FROM Cur INTO @Temp
WHILE @@FETCH_STATUS = 0
BEGIN
 SET @AllCounterIds = @AllCounterIds + '[' + @Temp + '],'
 FETCH NEXT FROM Cur INTO @Temp
END

CLOSE Cur
DEALLOCATE Cur

SET @AllCounterIds = SUBSTRING(@AllCounterIds, 0, LEN(@AllCounterIds))

SET @CounterIdQuery = 'SELECT DateTime, ' + @AllCounterIds + '
FROM 
(SELECT Type, DateTime, Value, AllCounterIds.CounterId
FROM AllCounterIds
 INNER JOIN AllCounters
  ON AllCounterIds.CounterId = AllCounters.CounterId) S
PIVOT
(
SUM (Value)
FOR CounterId IN
(' + @AllCounterIds + ')) AS pvt'

EXEC sp_executesql @CounterIdQuery
其中AllCounterId是我使用以下方法创建的视图:

GO
CREATE VIEW AllCounterIds AS 
SELECT DISTINCT CounterId FROM AllCounters
GO
所以问题是,到目前为止,我的表中大约有27993600行,当我执行SQL时,大约需要4分钟15秒才能得到输出,而根据性能要求,它的错误。。。所以我的问题是,我在哪里可以达到我想要的结果,但得到更好的表现


为了让您知道,表中也定义了集群索引…

我不确定对于您的情况来说,它实际上更快,但也许可以尝试类似的方法

declare
    @allcounterids varchar(max),
    @counteridquery varchar(max)
;

select
    @allcounterids = stuff((
    select 
            '],[' + cast([CounterId] as varchar(32))
        from
            allcounterids
        for xml path('')), 1, 2, '') + ']'
;

set @counteridquery = 'select
        s.datetime, pvt.*
    from
        (SELECT Type, DateTime, Value, AllCounterIds.CounterId
            FROM AllCounterIds
            INNER JOIN AllCounters
                ON AllCounterIds.CounterId = AllCounters.CounterId
        ) S
        PIVOT
        (
            SUM (Value)
            FOR CounterId IN
            (' + @AllCounterIds + ')
        ) AS pvt;'
;
execute(@counteridquery);

使用
varchar
而不是
nvarchar
是故意的。不太可能需要使用unicode来创建整数列表,这将节省一些内存,因此可能会节省时间。

我假设您已经在这个查询上运行了sql profiler?不明白您的意思。。。您能解释更多内容并提供一些替代方案吗?运行此操作时出现以下错误-->无法绑定多部分标识符“s.datetime”。@dvlpr:这只是一个示例,可能无法直接运行。总之,结尾的
set
语句是你的代码,不是我的。如果我的版本坏了,直接用你的。有趣的区别只是在构造透视列表的方式上。使用nvarchar的需要是我正在使用的过程的要求。。。尝试将其设置为varchar,但出现错误,表示它只能执行以下ntext/nchar之一/nvarchar@dvlpr:在这种情况下,请切换到nvarchar。注意区分大小写。如果系统区分大小写,则错误可能是因为列引用
s.datetime
与派生表
s
的大小写不匹配。