2012-10-19 64 views
1

這是我第一次嘗試動態旋轉SQL,並且我已經變得有點卡住了!動態SQL樞軸 - 刪除空值

我有兩張表格,我持有兩個表格,一個持有庫存物品,另一個持有不同價格的不同網站(來源)的庫存物品。由於有不同網站的可能性,查詢需要是動態的。

問題是我無法從結果中刪除空值,我希望有人能幫忙。

結果看起來像這樣目前:

ID site-site1 site-site2 site-site3 
1  null   1.99   2.99 
2  12.99   null   10.00 
3  1.50   null   2.00 

查詢如下:

DECLARE @sources nvarchar(max) 

SELECT @sources = 
STUFF((SELECT DISTINCT ',[' + 
CASE 
WHEN ip.[Source] is null or ip.[Source] = '' THEN 'Default' 
ELSE ip.[Source] 
END 
+ ' - ' + 
CASE 
WHEN ip.secondSource is null or ip.secondSource = '' THEN 'Default' 
ELSE ip.secondSource 
END 
+ ']' 
    FROM itemprice ip 
    for XML PATH('') 
), 1, 1, '') 

DECLARE @SQL nvarchar(MAX) 
SELECT @SQL = N' 
SELECT * 
FROM 
(
SELECT 
s.id, 
[Source] = CASE 
       WHEN ip.[Source] is null or ip.[Source] = '''' THEN ''Default'' 
     ELSE ip.[Source] 
     END + '' - '' + 
CASE WHEN ip.secondSource is null or ip.secondSource = '''' THEN ''Default'' 
ELSE ip.secondSource 
END, 
    SalePrice = isnull(ip.SalePrice, 0) 
    FROM stock s 
    LEFT OUTER JOIN itemprice ip on ip.id = s.id 
) data 
PIVOT 
( 
    MAX(SalePrice) for [Source] IN (' + @sources + ') 
) as PivotTable 
ORDER BY PivotTable.id' 
exec sp_executesql @sql 

任何幫助將不勝感激,它看起來好像它並不像包裝每一樣簡單@源項目在ISNULL。

謝謝

+0

你是什麼意思刪除空值?你想取代他們的位置? – podiluska

+0

抱歉應該更清楚了,在這種情況下,我需要0s –

回答

2

不幸的是,你必須ISNULL每個單獨的透視列。無論是或CROSS JOIN你的data子查詢生成完整的矩陣,並在那裏執行ISNULL。

例如使用樞軸列上的ISNULL替換NULL的NULL值:

DECLARE @sources nvarchar(max), @Selectlist nvarchar(max) 

SELECT @sources = 
STUFF((SELECT DISTINCT ',[' + 
CASE 
WHEN ip.[Source] is null or ip.[Source] = '' THEN 'Default' 
ELSE ip.[Source] 
END 
+ ' - ' + 
CASE 
WHEN ip.secondSource is null or ip.secondSource = '' THEN 'Default' 
ELSE ip.secondSource 
END 
+ ']' 
    FROM itemprice ip 
    for XML PATH('') 
), 1, 1, '') 

SELECT @Selectlist = 
STUFF((SELECT DISTINCT ',ISNULL([' + 
CASE 
WHEN ip.[Source] is null or ip.[Source] = '' THEN 'Default' 
ELSE ip.[Source] 
END 
+ ' - ' + 
CASE 
WHEN ip.secondSource is null or ip.secondSource = '' THEN 'Default' 
ELSE ip.secondSource 
END 
+ '],0) [' + 
CASE 
WHEN ip.[Source] is null or ip.[Source] = '' THEN 'Default' 
ELSE ip.[Source] 
END 
+ ' - ' + 
CASE 
WHEN ip.secondSource is null or ip.secondSource = '' THEN 'Default' 
ELSE ip.secondSource 
END 
+ ']' 
    FROM itemprice ip 
    for XML PATH('') 
), 1, 1, '') 

DECLARE @SQL nvarchar(MAX) 
SELECT @SQL = N' 
SELECT ID, ' + @Selectlist + ' 
FROM 
(
SELECT 
s.id, 
[Source] = CASE 
       WHEN ip.[Source] is null or ip.[Source] = '''' THEN ''Default'' 
     ELSE ip.[Source] 
     END + '' - '' + 
CASE WHEN ip.secondSource is null or ip.secondSource = '''' THEN ''Default'' 
ELSE ip.secondSource 
END, 
    SalePrice = isnull(ip.SalePrice, 0) 
    FROM stock s 
    LEFT OUTER JOIN itemprice ip on ip.id = s.id 
) data 
PIVOT 
( 
    MAX(SalePrice) for [Source] IN (' + @sources + ') 
) as PivotTable 
ORDER BY PivotTable.id' 
exec sp_executesql @sql 
+0

+1,但是,最好使用QUOTENAME(Column)而不是'''+ column +']'。如果其中一個動態創建的列包含'['或']','QUOTENAME'將會避免這種情況,並且最好確保輸出是一個有效的選擇列。 – GarethD

+0

雖然說過我認爲如果任何動態創建的列包含方括號,它會導致替換失敗...也許生成列表的列表爲樞軸和選擇單獨將是一個更強大的解決方案? – GarethD

+0

樞軸列表** IS **基本選擇列表。如果解決方案適用於OP,我不打算對不包含'[]'的列名進行賭注。但是,我個人使用'QUOTENAME'。 – RichardTheKiwi