SQL服务器怎么提动态列值不应该为空
SQL Server How to mention dynamic column value should not be null
先看几个截图。
查看第二个屏幕截图。其中 2010 FYA 和其余列是动态列。查看动态列值为 NULL 的第一条记录。现在告诉我如何在获取数据时提到动态列值不应该为空。
这是代码
Set @AvgSql = @AvgSql+ 'Avg(CONVERT(decimal(20,6),['+@Period+'])) ['+@Period+'],'
通过这种方式,我将动态列智能值存储到 #TmpZacksCons 临时 table.
SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,
'+@PeriodCols+'
)
Select b.Section, b.LineItem,Max(Ord)+1 Ord,
'+@AvgSql+'
From #TmpAll_Broker_LI b
Group By b.Section, b.LineItem'
EXEC(@sql)
这是我的最终查询,return 我需要过滤掉空值的整个数据。不应出现空数据。
SET @sql = '
Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,
Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator
From
(
---- Broker Detail
Select AA.Section,AA.LineItem,Csm.DisplayInCSM ,AA.BrokerCode Broker,AA.BrokerName,'''' BM_Element,'''' BM_Code,AA.Ord,AA.[Revise Date],AA.LineItemId,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From tblCSM_ModelDetails Csm LEFT OUTER JOIN (
Select b.*,L.ID LineItemId
From #TmpAll_Broker_LI b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
) AA ON Csm.LineItemId=AA.LineItemId
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0 AND Type !=''SHEET''
UNION
----- Consensus
Select Section, b.LineItem,DisplayInCSM, '''' Broker,'''' BrokerName,'''' BM_Element,'''' BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpZacksCons b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0
---- Blue Metrics
UNION
Select Section, b.LineItem,DisplayInCSM,'''' Broker,'''' BrokerName,BM_Element,Code BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpBM b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.BMID=b.code AND Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+'
AND Ord IS NOT NULL
) XX
Left Outer Join tblLiConfig ZZ
On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+@Ticker+'''
Order by ID,Ord,BM_Code,LineItem,BrokerName'
好的...对不起,这是一个错误的答案。 真的 糟糕的答案。当您现在需要修复但没有时间正确修复问题时,这是一种答案。
真正的解决方法是排除没有有效值的行,然后再将它们组合到用于创建 table 的数据集中。但是,如果不更深入地了解您的 processes/data,我就无法做到这一点。相反,我有一个完整的 hackjob。
无论如何,据我所知
- 在 table #TmpZacksCons
- 您有一些行,其中所有与日期相关的列都是 NULL
- 而您想排除那些
- 列名是动态设置的 - 它们在变量@PeriodCols 中
您可以做的是从#TmpZacksCons 中删除全部为 NULLS 的行。当然,问题是这些列是动态创建的。
所以,在你现有的命令之后
SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,
'+@PeriodCols+'
)
Select b.Section, b.LineItem,Max(Ord)+1 Ord,
'+@AvgSql+'
From #TmpAll_Broker_LI b
Group By b.Section, b.LineItem'
EXEC(@sql)
我建议使用 DELETE 命令删除所有列均为 NULL 的命令。
更新
(这个新版本基于更新的知识 - 我不认为 COALESCE 可以 return NULL)
这里的 hackjob 是基于我们不知道列名的事实,所以我们不能只测试列 1 是否为空,列 2 是否为空等。
所以我正在做的是使用 COALESCE 表达式来查找是否所有列都是 NULL,因为它将 return 列表中的第一个非 NULL 值。
SET @sql='DELETE FROM #TmpZacksCons
WHERE COALESCE('+@PeriodCols+',NULL) IS NULL'
EXEC (@sql)
如果 COALESCE 表达式 return 为 NULL,则表示所有列都具有 NULL 值。
请注意,在列列表只有 1 列的情况下,COALESCE 中还有额外的 NULL。
以前的版本 - 不再相关
所以我正在做的是创建一个 'magic number' 表示所有列都是 NULL 通过 COALESCE 表达式找到第一个非 NULL 值列表.
所以,在你上面的命令之后,我建议
SET @sql='DELETE FROM #TmpZacksCons
WHERE COALESCE('+@PeriodCols+',-99999.9999) = -99999.9999'
EXEC (@sql)
如果所有值为 NULL,COALESCE 将 return -99999.9999 然后触发删除。
当然,上面的问题是,如果任何 实际 值等于幻数 -99999.9999,它可能会删除该行。
先看几个截图。
查看第二个屏幕截图。其中 2010 FYA 和其余列是动态列。查看动态列值为 NULL 的第一条记录。现在告诉我如何在获取数据时提到动态列值不应该为空。
这是代码
Set @AvgSql = @AvgSql+ 'Avg(CONVERT(decimal(20,6),['+@Period+'])) ['+@Period+'],'
通过这种方式,我将动态列智能值存储到 #TmpZacksCons 临时 table.
SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,
'+@PeriodCols+'
)
Select b.Section, b.LineItem,Max(Ord)+1 Ord,
'+@AvgSql+'
From #TmpAll_Broker_LI b
Group By b.Section, b.LineItem'
EXEC(@sql)
这是我的最终查询,return 我需要过滤掉空值的整个数据。不应出现空数据。
SET @sql = '
Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,
Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator
From
(
---- Broker Detail
Select AA.Section,AA.LineItem,Csm.DisplayInCSM ,AA.BrokerCode Broker,AA.BrokerName,'''' BM_Element,'''' BM_Code,AA.Ord,AA.[Revise Date],AA.LineItemId,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From tblCSM_ModelDetails Csm LEFT OUTER JOIN (
Select b.*,L.ID LineItemId
From #TmpAll_Broker_LI b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
) AA ON Csm.LineItemId=AA.LineItemId
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0 AND Type !=''SHEET''
UNION
----- Consensus
Select Section, b.LineItem,DisplayInCSM, '''' Broker,'''' BrokerName,'''' BM_Element,'''' BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpZacksCons b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0
---- Blue Metrics
UNION
Select Section, b.LineItem,DisplayInCSM,'''' Broker,'''' BrokerName,BM_Element,Code BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,
Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],
'+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment
From #TmpBM b
INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem
INNER JOIN tblCSM_ModelDetails Csm ON Csm.BMID=b.code AND Csm.LineItemID=L.ID
WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+'
AND Ord IS NOT NULL
) XX
Left Outer Join tblLiConfig ZZ
On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+@Ticker+'''
Order by ID,Ord,BM_Code,LineItem,BrokerName'
好的...对不起,这是一个错误的答案。 真的 糟糕的答案。当您现在需要修复但没有时间正确修复问题时,这是一种答案。
真正的解决方法是排除没有有效值的行,然后再将它们组合到用于创建 table 的数据集中。但是,如果不更深入地了解您的 processes/data,我就无法做到这一点。相反,我有一个完整的 hackjob。
无论如何,据我所知
- 在 table #TmpZacksCons
- 您有一些行,其中所有与日期相关的列都是 NULL
- 而您想排除那些
- 列名是动态设置的 - 它们在变量@PeriodCols 中
您可以做的是从#TmpZacksCons 中删除全部为 NULLS 的行。当然,问题是这些列是动态创建的。
所以,在你现有的命令之后
SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,
'+@PeriodCols+'
)
Select b.Section, b.LineItem,Max(Ord)+1 Ord,
'+@AvgSql+'
From #TmpAll_Broker_LI b
Group By b.Section, b.LineItem'
EXEC(@sql)
我建议使用 DELETE 命令删除所有列均为 NULL 的命令。
更新
(这个新版本基于更新的知识 - 我不认为 COALESCE 可以 return NULL)
这里的 hackjob 是基于我们不知道列名的事实,所以我们不能只测试列 1 是否为空,列 2 是否为空等。 所以我正在做的是使用 COALESCE 表达式来查找是否所有列都是 NULL,因为它将 return 列表中的第一个非 NULL 值。
SET @sql='DELETE FROM #TmpZacksCons
WHERE COALESCE('+@PeriodCols+',NULL) IS NULL'
EXEC (@sql)
如果 COALESCE 表达式 return 为 NULL,则表示所有列都具有 NULL 值。
请注意,在列列表只有 1 列的情况下,COALESCE 中还有额外的 NULL。
以前的版本 - 不再相关
所以我正在做的是创建一个 'magic number' 表示所有列都是 NULL 通过 COALESCE 表达式找到第一个非 NULL 值列表.
所以,在你上面的命令之后,我建议
SET @sql='DELETE FROM #TmpZacksCons
WHERE COALESCE('+@PeriodCols+',-99999.9999) = -99999.9999'
EXEC (@sql)
如果所有值为 NULL,COALESCE 将 return -99999.9999 然后触发删除。
当然,上面的问题是,如果任何 实际 值等于幻数 -99999.9999,它可能会删除该行。