2015-07-21 48 views
0

我有這個轉動表得到上一行的值,如果行是NULL

+---------+----------+----------+-----+----------+ 
| Date | Product1 | Product2 | ... | ProductN | 
+---------+----------+----------+-----+----------+ 
| 7/1/15 | 5  | 2  | ... | 7  | 
| 8/1/15 | 7  | 1  | ... | 9  | 
| 9/1/15 | NULL  | 7  | ... | NULL  | 
| 10/1/15 | 8  | NULL  | ... | NULL  | 
| 11/1/15 | NULL  | NULL  | ... | NULL  | 
+---------+----------+----------+-----+----------+ 

我想填寫上面他們值NULL列。所以,輸出應該是這樣的。

+---------+----------+----------+-----+----------+ 
| Date | Product1 | Product2 | ... | ProductN | 
+---------+----------+----------+-----+----------+ 
| 7/1/15 | 5  | 2  | ... | 7  | 
| 8/1/15 | 7  | 1  | ... | 9  | 
| 9/1/15 | 7  | 7  | ... | 9  | 
| 10/1/15 | 8  | 7  | ... | 9  | 
| 11/1/15 | 8  | 7  | ... | 9  | 
+---------+----------+----------+-----+----------+ 

我發現這個article可能會幫助我,但這隻能操縱一列。我如何將這個應用到我的所有專欄,或者我的專欄是動態的,我怎樣才能達到這樣的結果。

任何幫助將不勝感激。謝謝!

+2

我的猜測是,在擺動之前這樣做會容易得多。 –

+0

是的。但我無法找到任何方式來確定什麼是NULL列 –

+0

這是原始數據中不存在的行(假設您實際上沒有NULL值) –

回答

0

ANSI標準的選件LAG()。這是,正好是你想要什麼。唉,SQL Server還沒有(還)?實現了這個功能。

所以,你可以用幾種方法來做到這一點。一個使用多個outer apply s。另一個使用相關子查詢:

select p.date, 
     (case when p.product1 is not null else p.product1 
      else (select top 1 p2.product1 from pivoted p2 where p2.date < p.date order by p2.date desc) 
     end) as product1, 
     (case when p.product1 is not null else p.product1 
      else (select top 1 p2.product1 from pivoted p2 where p2.date < p.date order by p2.date desc) 
     end) as product1, 
     (case when p.product2 is not null else p.product2 
      else (select top 1 p2.product2 from pivoted p2 where p2.date < p.date order by p2.date desc) 
     end) as product2, 
     . . . 
from pivoted p ; 

我會建議在date索引此查詢。

+0

嗨。你會如何動態地做到這一點?因爲我不知道「產品」是什麼。 –

+0

@BoyPasmo。 。 。這將是一個非常不同的問題。我建議你問問題*和*包括你用於數據透視的代碼。 –

0

我想推薦你一個解決方案。如果您有一張只包含兩列的表格,我的解決方案將完美運作。

+---------+----------+ 
| Date | Product | 
+---------+----------+ 
| 7/1/15 | 5  | 
| 8/1/15 | 7  | 
| 9/1/15 | NULL  | 
| 10/1/15 | 8  | 
| 11/1/15 | NULL  | 
+---------+----------+ 

select x.[Date], 
     case 
      when x.[Product] is null 
      then min(c.[Product]) 
     else 
      x.[Product] 
     end as Product 
from 
(
    -- this subquery evaluates a minimum distance to the rows where Product column contains a value 
    select [Date], 
      [Product], 
      min(case when delta >= 0 then delta else null end) delta_min, 
      max(case when delta < 0 then delta else null end) delta_max 
    from 
    (
     -- this subquery maps Product table to itself and evaluates the difference between the dates 
     select p.[Date], 
       p.[Product], 
       DATEDIFF(dd, p.[Date], pnn.[Date]) delta 
     from @products p 
     cross join (select * from @products where [Product] is not null) pnn 
    ) x 
    group by [Date], [Product] 
) x 
left join @products c on x.[Date] = 
    case 
     when abs(delta_min) < abs(delta_max) then DATEADD(dd, -delta_min, c.[Date]) 
     else DATEADD(dd, -delta_max, c.[Date]) 
    end 
group by x.[Date], x.[Product] 
order by x.[Date] 

在此查詢中,我將表映射到包含CROSS JOIN語句值的自身行。然後,我計算日期之間的差異,以便挑選最接近的日期,然後用值填充空白單元格。

結果:

+---------+----------+ 
| Date | Product | 
+---------+----------+ 
| 7/1/15 | 5  | 
| 8/1/15 | 7  | 
| 9/1/15 | 7  | 
| 10/1/15 | 8  | 
| 11/1/15 | 8  | 
+---------+----------+ 

其實,建議查詢不會選擇以前的值。而不是這個,它選擇最接近的值。換句話說,我的代碼可以用於許多不同的目的。

相關問題