2017-06-28 7 views
2

まだ回答が見つかりませんでしたので、これは不可能です。MS SQL Server 2014ピボット列の最後の既知の値を使用して、ラグ付きの動的ピボットを選択してください

ピボットされたNULL行を、NULLでない列に使用可能な最後の値で置き換えるピボットクエリを探しています。最初の行がNullの場合、行は値があるまでNULLになります。

CIDが変更されると、行は新しい行として開始されます。したがって、CID 3の最初の行がNullの場合、値はNULLです。ここで

は私のピボットクエリです

DECLARE @Columns AS VARCHAR(MAX) 
DECLARE @Query VARCHAR(MAX) 
DECLARE @TEMP_DB VARCHAR(255) 
SET @TEMP_DB = 'Demo_DataSet' 

SELECT @Columns = 
     COALESCE(@Columns + ', ','') + QUOTENAME(AttrName) 
FROM 
(
    SELECT DISTINCT AttrName 
FROM Demo_FirstPass_Data_Raw 
) AS B 
ORDER BY B.AttrName 

SET @Query = ' 

WITH PivotData AS 
(
    SELECT 
      DocID 
     , Customer 
     , Version 
     , CID 
     , AttrName 
     , AttrText 
    FROM Demo_FirstPass_Data_Raw 
) 

SELECT 
     DocID 
    , Customer 
    , Version 
    , CID 
    , ' + @Columns + ' 
INTO Demo_FirstPass_Data_Pivot 
FROM PivotData 
PIVOT 
(
    MAX(AttrText) 
    FOR AttrName 
    IN (' + @Columns + ') 
) AS PivotResult 
Where Version = Version 
ORDER BY DocID, Version, CID' 

DECLARE @SQL_SCRIPT VARCHAR(MAX) 

SET @SQL_SCRIPT = REPLACE(@Query, '' + @TEMP_DB + '', @TEMP_DB) 
EXECUTE (@SQL_SCRIPT) 

私の結果は、私が探しています何

DocID | Customer | Version | CID | Username | Sales_Order | Date | Description 
1852 | Acme  | 1 | 2 | User1 | NULL  | 11/17/2010 | Product 
1852 | Acme  | 2 | 2 | NULL | NULL  | NULL | NULL 
1852 | Acme  | 3 | 2 | NULL | NULL  | 12/15/2010 | NULL 
1852 | Acme  | 4 | 2 | NULL | NULL  | NULL | NULL 
1852 | Acme  | 5 | 2 | NULL | S-0001 | 11/17/2010 | NULL 
1852 | Acme  | 7 | 2 | NULL | S-0001 | NULL | NULL 
1852 | Acme  | 8 | 2 | NULL | NULL  | 1/14/2011 | NULL 
1852 | Acme  | 9 | 2 | NULL | NULL  | NULL | NULL 
1852 | Acme  | 10 | 2 | NULL | NULL  | NULL | NULL 
1852 | Acme  | 1 | 3 | User2 | NULL  | 10/10/2010 | Product 
1852 | Acme  | 2 | 3 | NULL | NULL  | NULL | NULL 
1852 | Acme  | 3 | 3 | NULL | NULL  | 12/15/2010 | NULL 

あるすべてのヘルプは高く評価され

DocID | Customer | Version | CID | Username | Sales_Order | Date | Description 
1852 | Acme  | 1 | 2 | User1 | NULL  | 11/17/2010 | Product 
1852 | Acme  | 2 | 2 | User1 | NULL  | 11/17/2010 | Product 
1852 | Acme  | 3 | 2 | User1 | NULL  | 12/15/2010 | Product 
1852 | Acme  | 4 | 2 | User1 | NULL  | 12/15/2010 | Product 
1852 | Acme  | 5 | 2 | User1 | S-0001 | 11/17/2010 | Product 
1852 | Acme  | 7 | 2 | User1 | S-0001 | 11/17/2010 | Product 
1852 | Acme  | 8 | 2 | User1 | S-0001 | 1/14/2011 | Product 
1852 | Acme  | 9 | 2 | User1 | S-0001 | 1/14/2011 | Product 
1852 | Acme  | 10 | 2 | User1 | S-0001 | 1/14/2011 | Product 
1852 | Acme  | 1 | 3 | User2 | NULL  | 10/10/2010 | Product 
1852 | Acme  | 2 | 3 | User2 | NULL  | 10/10/2010 | Product 
1852 | Acme  | 3 | 3 | User2 | NULL  | 12/15/2010 | Product 

です。列の数が不明の場合

+0

少し時間が必要です。 – Chuck

答えて

0

と1つのオプション再帰CTEのためのコードを生成し、そのようなあなたのパーティションに基づいて、最後の非ヌル値を保持するためにそれを使用することで、動的なピボットに統合する:

declare @Columns as nvarchar(max) 
declare @Query nvarchar(max) 
declare @temp_db nvarchar(255) 
set @temp_db = 'Demo_DataSet' 

select @Columns = 
     coalesce(@Columns + ', ','') + quotename(AttrName) 
from 
(
    select distinct AttrName 
from Demo_FirstPass_Data_Raw 
) as B 
order by B.AttrName 

/* generate isnull statements for columns in recursive cte */ 
declare @isnull nvarchar(max) = stuff((
    select distinct ', isnull(t.'+quotename(d.AttrName)+',cte.'+quotename(d.AttrName)+')' 
    from Demo_FirstPass_Data_Raw d 
    order by 1 
    for xml path (''), type).value('(./text())[1]','nvarchar(max)') 
    ,1,2,'') 

set @Query = 'with PivotData as (
    select Docid, Customer, Version, cid, AttrName, AttrText 
    from Demo_FirstPass_Data_Raw 
) 
, t as (
    select 
     Docid, Customer, Version, cid 
     , ' + @Columns + ' 
     , rn = row_number() over (partition by DocId, Customer, cid order by Version) 
    from PivotData 
    pivot(max(AttrText) for AttrName in (' + @Columns + ')) as PivotResult 
) 
, cte as (
    select [Docid], [Customer], [Version], [cid], ' + @Columns + ', rn 
    from t 
    where version = 1 
    union all 
    select t.[Docid], t.[Customer], t.[Version], t.[cid] 
     , '+ @isnull + ' 
     '+',t.rn 
    from t 
    inner join cte 
     on t.rn = cte.rn+1 
    and t.docid = cte.docid 
    and t.customer = cte.customer 
    and t.cid = cte.cid 
) 
select * 
from cte 
order by docid, customer, cid, version 
' 

select @query 
exec sp_executesql @query 

rextesterデモ:生成http://rextester.com/OQZOW62536

コード:

with PivotData as (
    select Docid, Customer, Version, cid, AttrName, AttrText 
    from Demo_FirstPass_Data_Raw 
) 
, t as (
    select 
     Docid, Customer, Version, cid 
     , [Date], [Description], [Sales_Order], [Username] 
     , rn = row_number() over (partition by DocId, Customer, cid order by Version) 
    from PivotData 
    pivot(max(AttrText) for AttrName in ([Date], [Description], [Sales_Order], [Username])) as PivotResult 
) 
, cte as (
    select [Docid], [Customer], [Version], [cid], [Date], [Description], [Sales_Order], [Username], rn 
    from t 
    where version = 1 
    union all 
    select t.[Docid], t.[Customer], t.[Version], t.[cid] 
     , isnull(t.[Date],cte.[Date]), isnull(t.[Description],cte.[Description]), isnull(t.[Sales_Order],cte.[Sales_Order]), isnull(t.[Username],cte.[Username]) 
     ,t.rn 
    from t 
    inner join cte 
     on t.rn = cte.rn+1 
    and t.docid = cte.docid 
    and t.customer = cte.customer 
    and t.cid = cte.cid 
) 
select * 
from cte 
order by docid, customer, cid, version 

結果:

+-------+----------+---------+-----+------------+-------------+-------------+----------+----+ 
| Docid | Customer | Version | cid | Date | Description | Sales_Order | Username | rn | 
+-------+----------+---------+-----+------------+-------------+-------------+----------+----+ 
| 1852 | Acme  |  1 | 2 | 2010-11-17 | Product  | NULL  | User1 | 1 | 
| 1852 | Acme  |  2 | 2 | 2010-11-17 | Product  | NULL  | User1 | 2 | 
| 1852 | Acme  |  3 | 2 | 2010-12-15 | Product  | NULL  | User1 | 3 | 
| 1852 | Acme  |  4 | 2 | 2010-12-15 | Product  | NULL  | User1 | 4 | 
| 1852 | Acme  |  5 | 2 | 2010-11-17 | Product  | S-0001  | User1 | 5 | 
| 1852 | Acme  |  7 | 2 | 2010-11-17 | Product  | S-0001  | User1 | 6 | 
| 1852 | Acme  |  8 | 2 | 2011-01-14 | Product  | S-0001  | User1 | 7 | 
| 1852 | Acme  |  9 | 2 | 2011-01-14 | Product  | S-0001  | User1 | 8 | 
| 1852 | Acme  |  10 | 2 | 2011-01-14 | Product  | S-0001  | User1 | 9 | 
| 1852 | Acme  |  1 | 3 | 2010-10-10 | Product  | NULL  | User2 | 1 | 
| 1852 | Acme  |  2 | 3 | 2010-10-10 | Product  | NULL  | User2 | 2 | 
| 1852 | Acme  |  3 | 3 | 2010-12-15 | Product  | NULL  | User2 | 3 | 
+-------+----------+---------+-----+------------+-------------+-------------+----------+----+ 
+0

十分にありがとうございます。私は数日間その答えを追いかけてきました。 – Chuck

+0

@チャックお手伝いします! – SqlZim

関連する問題