首页 > 解决方案 > SQL Server:如何按顺序从许多其他列中自定义 Order By 子句中的一列

问题描述

我有一个可以很好地返回数据的存储过程,它是由现在没有联系的其他人开发的。

输出现在看起来像 在此处输入图像描述

在这里,我附上了返回数据的查询的一部分。

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'      

现在经纪人姓名不是按字母顺序排列的,这是问题所在。

在底部看到这条线Order by ID,Ord,BM_Code,LineItem,BrokerName

当我尝试通过 like 更改此顺序时,Order by ID,Ord,BM_Code,LineItem,BrokerName IN (SELECT BrokerName FROM #Brokers ORDER BY BrokerName ASC)' 出现错误 like子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。

在我的订单中,有很多列,数据通过这种方式得到订单,但我需要按字母顺序显示经纪人名称,但我做不到。所以请有人指导我如何自定义这个 sql。

在这里我没有附上我的完整存储过程代码,因为它非常大。寻求建议和帮助。谢谢

标签: tsql

解决方案


精简版

ORDER BY正在执行预期的操作 - 首先按 ID 排序,然后是 Ord,然后是 BM_Code,然后是 LineItem,然后是 BrokerName 。

在 ID 76187 中,下一个排序依据是Ord- 从 30911 到 31097 排序。

如果它以前由 BrokerName 订购,那只是偶然 - 或者 Ord 的订购方式与 BrokerName 相同。

我最初的建议是重新排序您的排序,例如,ORDER BY ID, BM_Code, LineItem, BrokerName, Ord

更长的问题解释

在 SQL 中,基础数据被视为一个集合,排序无关紧要。

例如,如果您有一个变量 @x 并且您正在测试IF @x IN (1,2,3,4,5)将产生与IF @x in (5,4,3,2,1).

在您的示例中,您将 ORDER BY 放入您使用 IN 检查的子查询中,例如ORDER BY ... BrokerName IN (SELECT BrokerName FROM #Brokers ORDER BY BrokerName ASC). 该子查询的顺序是不允许的,无论如何也不会做任何事情。

唯一重要的排序(除了一些像 TOP 的东西)是最终排序 - 在显示数据时。

话虽如此,即使您在子查询中删除了 ORDER BY,它也无助于您的问题

  • SQL 无论如何都不可能工作 - ORDER BY 需要一个值 - 你可能需要让它CASE WHEN BrokerName IN (...) THEN 0 ELSE 1 END
  • 这也无济于事,因为问题是无论如何都已Ord排序。BrokerName

更新以下评论

从根本上说,提供实际报告的语句是

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 (<a whole lot of calculations/cpode>) 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'    

那里的最后一行提供了来自此过程的数据的排序。

要获得不同的顺序,您需要更改显示字段的顺序 - 将 BrokerName 移到列表的开头,将 Ord 移到列表的末尾。

例如,

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 (<a whole lot of calculations/cpode>) XX       
    Left Outer Join tblLiConfig ZZ
        On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+@Ticker+'''      
Order by ID,BrokerName,BM_Code,LineItem,Ord'  

以上内容可能过早地按 BrokerName 排序 - 但由您决定您需要什么。


推荐阅读