我有一个存储过程,它从一个表中获取数据,运行我的动态数据透视存储过程,然后输出到页面中。问题是,有大量的空条目。当我在页面上处理这些数据时,我需要为每个TerminalID添加每个燃料数量。当它遇到空条目时会出现问题。我不想让每个行和列读取过程以将null转换为0,并且希望在SP中这样做。
对于测试,我制作了这个脚本:
DECLARE @QUERY NVARCHAR(MAX)
, @Soucecolumn VARCHAR(MAX)
, @BeginningDate VARCHAR(MAX)
, @EndingDate VARCHAR(MAX)
, @CompanyID VARCHAR(2)
SET NOCOUNT ON;
SET @BeginningDate = CONVERT(VARCHAR(30), CAST('2004-01-01' AS DATE));
SET @EndingDate = CONVERT(VARCHAR(30), CAST('2007-01-01' AS DATE));
SET @CompanyID = CONVERT(INT, '2');
SET @Soucecolumn = STUFF((
SELECT DISTINCT ', \[' + CAST(FuelTypeID AS VARCHAR(4)) + '\]'
FROM tt_Manifest_Fuel_Distribution
FOR XML PATH ('')), 1, 1, '')
SET @QUERY = '(
SELECT ManifestID, TerminalID, ' + @Soucecolumn + '
FROM (
SELECT mfd.ManifestID, m.TerminalID, mfd.FuelTypeID, mfd.FuelQuantity
FROM tt_Manifest_Fuel_Distribution mfd, tt_Terminals t, tt_Fuel_Types ft, tt_Manifests m
WHERE mfd.FuelTypeID=ft.FuelTypeID
AND m.ManifestID=mfd.ManifestID
AND m.CompanyID= ' + @CompanyID + '
AND m.ManifestInsertDate BETWEEN ''' + @BeginningDate + ''' AND ''' + @EndingDate +
'''
) up
PIVOT (
MAX(FuelQuantity) FOR \[FuelTypeID\] IN (' + @Soucecolumn + ')
) AS pvt)'
EXEC sp_executesql @QUERY
示例数据是:
>ManifestID TerminalID 3 6 4 2 1 5
>417 1 NULL NULL NULL NULL NULL 2478
>421 1 NULL NULL NULL NULL 3458 NULL
>508 1 NULL NULL NULL NULL NULL 2471
>826 1 NULL NULL NULL NULL NULL 7464
>832 1 NULL NULL NULL NULL 3482 NULL
>833 1 1001 NULL NULL NULL 1492 NULL
>844 1 NULL NULL NULL NULL 2498 NULL
>870 1 NULL NULL NULL NULL 5991 2503
>872 1 NULL NULL NULL NULL 3494 NULL
>2 2 NULL NULL 5514 NULL NULL 2505
>43 2 NULL NULL NULL NULL 7011 NULL
>46 2 1005 NULL NULL NULL 5007 2510
>60 2 NULL NULL 3502 NULL NULL 4513
>63 2 NULL NULL 4505 NULL NULL 3008
>69 2 NULL NULL 4008 NULL 4508 NULL
>78 2 1007 NULL NULL NULL 5022 NULL
>79 2 NULL NULL 2505 NULL NULL NULL
我尝试在mfd.FuelQuantity周围和@Sourcecolumn周围放置ISNULL(,0)。 mfd.FuelQuantiity似乎没有变化,而@Sourcecolumn错误地声称ISNull()需要2个参数。
我是以错误的方式看待这个吗?
答案 0 :(得分:2)
我强烈建议远离弃用的隐式联接。
您需要将ISNULL()
合并到@sourcecolumn
子句中SELECT
列表中的每个项目中。它抛出错误的原因是因为您的整个列列表都包含在一个语句中:ISNULL(col1,col2,col3...,0)
您需要ISNULL(col1,0),ISNULL(col2,0)...
我建议您在SELECT
中使用单独的sourcecolumn变量。
类似的东西:
SET @Sourcecolumn2 = STUFF((SELECT distinct ',ISNULL(\[' + CAST(FuelTypeID as varchar(4)) + ',0)\]as '+ CAST(FuelTypeID as varchar(4)) +' FROM tt_Manifest_Fuel_Distribution
FOR XML PATH('')),1,1,'')
最终:
![Declare @QUERY NVARCHAR(MAX),
@Soucecolumn VARCHAR(MAX),
@Sourcecolumn2 VARCHAR(MAX),
@BeginningDate VARCHAR(MAX),
@EndingDate VARCHAR(MAX),
@CompanyID VARCHAR(2)
SET NOCOUNT ON;
SET @BeginningDate = convert(varchar(30), cast('2004-01-01' as date));
SET @EndingDate = convert(varchar(30), cast('2007-01-01' as date));
SET @CompanyID = convert(int, '2');
SET @Soucecolumn = STUFF((SELECT distinct ', \[' + CAST(FuelTypeID as varchar(4)) + '\]' FROM tt_Manifest_Fuel_Distribution
FOR XML PATH('')),1,1,'');
SET @Sourcecolumn2 = STUFF((SELECT distinct ',ISNULL(\[' + CAST(FuelTypeID as varchar(4)) + ',0)\] as '+ CAST(FuelTypeID as varchar(4))+' FROM tt_Manifest_Fuel_Distribution
FOR XML PATH('')),1,1,'');
SET @QUERY = '(SELECT ManifestID, TerminalID, ' + @Sourcecolumn2 + ' FROM (
SELECT mfd.ManifestID, m.TerminalID, mfd.FuelTypeID, mfd.FuelQuantity
FROM tt_Manifest_Fuel_Distribution mfd, tt_Terminals t, tt_Fuel_Types ft, tt_Manifests m
WHERE mfd.FuelTypeID=ft.FuelTypeID
AND m.ManifestID=mfd.ManifestID
AND m.CompanyID= ' + @CompanyID + '
AND m.ManifestInsertDate BETWEEN ''' + @BeginningDate + ''' AND ''' + @EndingDate +
''' ) up PIVOT (MAX(FuelQuantity) FOR \[FuelTypeID\] IN (' + @Soucecolumn + ')) AS pvt)'
exec sp_executesql @QUERY][1]
答案 1 :(得分:1)
考虑下表
以下是示例数据
SELECT * INTO #TEMP
FROM
(
SELECT '01/JAN/2014' [DATE],'A' NAME,100 MARKS
UNION ALL
SELECT '02/JAN/2014' [DATE],'A' NAME,120
UNION ALL
SELECT '02/JAN/2014' [DATE],'B' NAME,130
UNION ALL
SELECT '03/JAN/2014' [DATE],'B' NAME,115
UNION ALL
SELECT '01/JAN/2014' [DATE],'C' NAME,123
UNION ALL
SELECT '01/JAN/2014' [DATE],'C' NAME,134
UNION ALL
SELECT '03/JAN/2014' [DATE],'C' NAME,146
UNION ALL
SELECT '04/JAN/2014' [DATE],'C' NAME,149
)TAB
现在为pivot的变量选择不同的名称
DECLARE @cols NVARCHAR (MAX)
SET @cols = SUBSTRING((SELECT DISTINCT ',['+NAME+']'
FROM #TEMP GROUP BY NAME FOR XML PATH('')),2,8000)
现在您需要另一个变量来应用NULL to zero
逻辑
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SET @NulltoZeroCols = SUBSTRING((SELECT DISTINCT ',ISNULL(['+NAME+'],0) AS ['+NAME+']'
FROM #TEMP GROUP BY NAME FOR XML PATH('')),2,8000)
现在使用两个变量
来转动查询DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT DATE,' + @NulltoZeroCols + ' FROM
(
SELECT [DATE],NAME,MARKS FROM #TEMP
) x
PIVOT
(
SUM(MARKS)
FOR [NAME] IN (' + @cols + ')
) p
;'
EXEC SP_EXECUTESQL @query
最后你的结果如下