Sql server 从';表内的s(取消打印/交叉应用)

Sql server 从';表内的s(取消打印/交叉应用),sql-server,tsql,sql-server-2014,unpivot,cross-apply,Sql Server,Tsql,Sql Server 2014,Unpivot,Cross Apply,我的一个导入表有严重问题。我已将Excel文件导入SQL Server表。表ImportExcelFile现在看起来如下所示(简化): 现在,我想将这些值从Field1插入Field10到表AgeYear(在我原来的表中,大约有70列120行)。第一行(Age/Year,2010,2011,…)是标题行。列Field1是前导列。我想以以下格式保存这些值: +-----------+-----+------+--------+ | SheetName | Age | Year | Value |

我的一个导入表有严重问题。我已将Excel文件导入SQL Server表。表
ImportExcelFile
现在看起来如下所示(简化):

现在,我想将这些值从
Field1
插入
Field10
到表
AgeYear
(在我原来的表中,大约有70列120行)。第一行(
Age/Year
2010
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


你能帮我吗?

也许是另一种方法。这不是动态的,而是在交叉应用程序和联接的帮助下

缺点是必须定义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
返回


我找不到其他方法,所以我接受了你的答案。字段从来都不超过200个,所以我在
中声明了
@列
变量,而
循环看起来是这样的:
('Field2',Field2),('Field3',Field3).
并在
交叉应用中使用它作为
值。谢谢大家!@我很高兴这有帮助。我以为你会变得活力四射。我只是想用一个静态版本来说明。
;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