2017-06-28 20 views
2

私のインポートテーブルに重大な問題があります。 ExcelファイルをSQL Serverテーブルにインポートしました。テーブルImportExcelFileは今、この(簡体字)のようになります。テーブル内のテーブルから値を取得する(unpivot/cross apply)

+----------+-------------------+-----------+------------+--------+--------+-----+---------+ 
| 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 | 
+----------+-------------------+-----------+------------+--------+--------+-----+---------+ 

私は今、(私の元のテーブルでは、約70列と120行がある)テーブルAgeYearField1からField10にそれらの値を挿入します。最初の行(Age/Year20102011、...)がヘッダー行です。列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 'ループの中で'(' Field2 '、Field2)、(' Field3 '、Field3)...'のように '@ columns'変数を宣言し、それを使用しました'CROSS APPLY'の中に' VALUES'と呼ばれています。ありがとうございました! –

+0

@diiN__________ハッピーに助けられました。私はあなたが動的になると思った。静的なバージョンで説明したかっただけです。 –

関連する問題