2017-06-28 21 views
2

我的某个导入表格存在严重问题。我已将Excel文件导入到SQL Server表。表ImportExcelFile现在看起来像这样(简化):从表格中获取值(不透明/交叉应用)

+----------+-------------------+-----------+------------+--------+--------+-----+---------+ 
| ImportId | Excelfile   | SheetName | Field1  | Field2 | Field3 | ... | Field10 | 
+----------+-------------------+-----------+------------+--------+--------+-----+---------+ 
| 1  | C:\Temp\Test.xlsx | Sheet1 | Age/Year | 2010 | 2011 |  | 2018 | 
| 2  | C:\Temp\Test.xlsx | Sheet1 | 0   | Value1 | Value2 |  | Value9 | 
| 3  | C:\Temp\Test.xlsx | Sheet1 | 1   | Value1 | Value2 |  | Value9 | 
| 4  | C:\Temp\Test.xlsx | Sheet1 | 2   | Value1 | Value2 |  | Value9 | 
| 5  | C:\Temp\Test.xlsx | Sheet1 | 3   | Value1 | Value2 |  | Value9 | 
| 6  | C:\Temp\Test.xlsx | Sheet1 | 4   | Value1 | Value2 |  | Value9 | 
| 7  | C:\Temp\Test.xlsx | Sheet1 | 5   | NULL | NULL |  | NULL | 
+----------+-------------------+-----------+------------+--------+--------+-----+---------+ 

我现在要插入从Field1这些值Field10AgeYear(在我原来的表有70列和120行)。第一行(Age/Year2010,2011,...)是标题行。列Field1是领先的专栏。我想保存在以下格式的值:

+-----------+-----+------+--------+ 
| SheetName | Age | Year | Value | 
+-----------+-----+------+--------+ 
| Sheet1 | 0 | 2010 | Value1 | 
| Sheet1 | 0 | 2011 | Value2 | 
| ...  | ... | ... | ... | 
| Sheet1 | 0 | 2018 | Value9 | 
| Sheet1 | 1 | 2010 | Value1 | 
| Sheet1 | 1 | 2011 | Value2 | 
| ...  | ... | ... | ... | 
| Sheet1 | 1 | 2018 | Value9 | 
| ...  | ... | ... | ... | 
+-----------+-----+------+--------+ 

我试过下面的查询:

DECLARE @sql NVARCHAR(MAX) = 
    ';WITH cte AS 
    (
     SELECT i.SheetName, 
      ROW_NUMBER() OVER(PARTITION BY i.SheetName ORDER BY i.SheetName) AS rn, 
      ' + @columns + ' -- @columns = 'Field1, Field2, Field3, Field4, ...' 
     FROM dbo.ImportExcelFile i 
     WHERE i.Sheetname LIKE ''Sheet1'' 
    ) 
    SELECT SheetName, 
      age Age, 
      y.[Year] 
    FROM cte 
    CROSS APPLY 
    (
     SELECT Field1 age 
     FROM dbo.ImportExcelFile 
     WHERE SheetName LIKE ''Sheet1'' 
     AND ISNUMERIC(Field1) = 1 
    ) a (age) 
    UNPIVOT 
    (
     [Year] FOR [Years] IN (' + @columns + ') 
    ) y 
    WHERE rn = 1' 

EXEC (@sql) 

到目前为止,我得到了想要的年龄和年。我的问题是我不知道如何获得价值。与UNPIVOT我没有得到NULL值。相反,即使它们是源表中的NULL,也会使用相同的值填充整个表格。

你能帮我吗?

回答

1

也许是另一种方法。这不是动态的,但在CROSS APPLY和JOIN的帮助下...

缺点是您必须定义70个字段。

;with cte0 as (
       Select A.ImportId 
         ,A.SheetName 
         ,Age = A.Field1 
         ,B.* 
       From ImportExcelFile A 
       Cross Apply (values ('Field2',Field2) 
            ,('Field3',Field3) 
            ,('Field10',Field10) 
          ) B (Item,Value) 

      ) 
    ,cte1 as (Select * from cte0 where ImportId=1) 
Select A.SheetName 
     ,[Age] = try_convert(int,A.Age) 
     ,[Year] = try_convert(int,B.Value) 
     ,[Value] = A.Value 
    From cte0 A 
    Join cte1 B on A.Item=B.Item 
    Where A.ImportId>1 

返回

enter image description here

+0

我无法找到任何其他方式做到这一点,所以我接受你的答案。从来没有超过200个字段,所以我在'while'循环中声明了我的'@ columns'变量,看起来像这样:'('Field2',Field2),('Field3',Field3)...'并使用它在'CROSS APPLY'里面作为'VALUES'。谢谢! –

+0

@diiN__________对它有帮助。我以为你会变得有活力。我只是想用静态版本来说明。 –