代码之家  ›  专栏  ›  技术社区  ›  Brian

将动态生成的透视表获取到临时表中

  •  4
  • Brian  · 技术社区  · 16 年前

    我见过 this ,所以我知道如何使用动态生成的字段集创建透视表。我现在的问题是我想把结果放到一个临时表中。

    我知道为了将结果集从 执行程序 语句需要预先定义临时表。对于动态生成的透视表,无法预先知道字段。

    我能想到的获得这种功能的唯一方法是使用动态SQL创建一个永久表。有更好的方法吗?

    4 回复  |  直到 7 年前
        1
  •  1
  •   Mladen Prajdic    16 年前

    你可以这样做:

    -- add 'loopback' linkedserver 
    if exists (select * from master..sysservers where srvname = 'loopback')
        exec sp_dropserver 'loopback'
    go
    exec sp_addlinkedserver @server = N'loopback',
        @srvproduct = N'',
        @provider = N'SQLOLEDB', 
        @datasrc = @@servername
    go
    
    declare @myDynamicSQL varchar(max)
    select @myDynamicSQL = 'exec sp_who'
    exec('
        select * into #t from openquery(loopback, ''' + @myDynamicSQL + ''');
        select * from #t
        ')
    

    编辑:添加动态SQL以接受参数到OpenQuery

        2
  •  2
  •   KnarfaLingus Ashish Gupta    7 年前

    今天就出现了这个问题,并在我的 blog . 解决方案的简短描述是创建一个具有一列的临时表,然后使用sp_executesql动态更改它。然后可以将动态轴的结果插入其中。下面的工作示例。

    CREATE TABLE #Manufacturers
    (
        ManufacturerID INT PRIMARY KEY,
        Name VARCHAR(128)
    )
    
    INSERT INTO #Manufacturers (ManufacturerID, Name)
    VALUES (1,'Dell')
    INSERT INTO #Manufacturers (ManufacturerID, Name)
    VALUES (2,'Lenovo')
    INSERT INTO #Manufacturers (ManufacturerID, Name)
    VALUES (3,'HP')
    
    CREATE TABLE #Years
    (YearID INT, Description VARCHAR(128))
    GO
    
    INSERT INTO #Years (YearID, Description) VALUES (1, '2014')
    INSERT INTO #Years (YearID, Description) VALUES (2, '2015')
    GO
    
    CREATE TABLE #Sales
    (ManufacturerID INT, YearID INT,Revenue MONEY)
    GO
    
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,2,59000000000)
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,2,46000000000)
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,2,111500000000)
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,1,55000000000)
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,1,42000000000)
    INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,1,101500000000)
    GO
    
    DECLARE @SQL AS NVARCHAR(MAX)
    DECLARE @PivotColumnName AS NVARCHAR(MAX)
    DECLARE @TempTableColumnName AS NVARCHAR(MAX)
    DECLARE @AlterTempTable AS NVARCHAR(MAX)
    
    --get delimited column names for various SQL statements below
    SELECT 
        -- column names for pivot
        @PivotColumnName= ISNULL(@PivotColumnName + N',',N'') + QUOTENAME(CONVERT(NVARCHAR(10),YearID)),
        -- column names for insert into temp table
        @TempTableColumnName = ISNULL(@TempTableColumnName + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)),
        -- column names for alteration of temp table
        @AlterTempTable = ISNULL(@AlterTempTable + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)) + ' MONEY' 
    FROM (SELECT DISTINCT [YearID] FROM #Sales) AS Sales
    
    CREATE TABLE #Pivot
    (
         ManufacturerID INT
    )
    
    -- Thats it! Because the following step will flesh it out.
    
    SET @SQL = 'ALTER TABLE #Pivot ADD ' + @AlterTempTable
    EXEC sp_executesql @SQL
    
    --execute the dynamic PIVOT query into the temp table 
    SET @SQL =  N'
        INSERT INTO #Pivot (ManufacturerID, ' + @TempTableColumnName + ')
        SELECT ManufacturerID, ' + @PivotColumnName + '
        FROM #Sales S
        PIVOT(SUM(Revenue) 
          FOR S.YearID IN (' + @PivotColumnName + ')) AS PivotTable'
    EXEC sp_executesql @SQL
    
    SELECT M.Name, P.*
    FROM #Manufacturers M
    INNER JOIN #Pivot P ON M.ManufacturerID = P.ManufacturerID
    
        3
  •  1
  •   Min    16 年前

    让我来尝试一下这个关于select into的解释。我也在运行SQL Server 2005。因为你有数据透视表,所以我假设2008年也一样。

    select 
        o.*,
        OtherField1,
        OtherField2
    INTO #temp
    FROM
        OriginalOtherData as ood
    PIVOT (
        MAX([Value])
        FOR Field in (OtherField1, OtherField2)
    ) as piv
    RIGHT OUTER join
        Original o on o.OriginalSD = piv.OriginalSD
    
    select * from #temp
    Drop table #temp
    

    这个 只有 普通select和select into的区别在于into_table部分。

        4
  •  0
  •   Amicable    11 年前
    • 用于查询(从tablename中选择col1、col2、col3
    • 第1列变为行标签
    • 第2列变为列标题
    • col3是数据集

    • 同时除去全局表

      if OBJECT_ID('tempdb..#3') is not null drop table #3
      if OBJECT_ID('tempdb..##3') is not null drop table ##3
      DECLARE @cols AS NVARCHAR(MAX),
          @query  AS NVARCHAR(MAX)
      select @cols = STUFF((SELECT distinct ',' + QUOTENAME(   col2    ) from    tablename    FOR XML PATH(''), col2).value('.', 'NVARCHAR(MAX)'),1,1,'')
      set @query = 'SELECT col1, ' + @cols + ' into ##3 from ( select col1, col2, col3 from tablename ) x  pivot (  max(col3)for col2 in (' + @cols + ')) p '
      execute(@query)   
      select * into #3 from ##3 if OBJECT_ID('tempdb..##3') -- is not null drop table ##3