使用 count 和 sum 以及 top 的多列子查询
Subquery with multiple colums using count and sum and top
正在创建以下临时文件-table:
CREATE TABLE #BEDRAGEN(Dossiercode T_Code_Dossier,Detailcode T_Code_Detail,DetailSubcode T_Code_DetailSub
,Totaalbedrag T_Fin_Amount,TotGefactDiensten T_Fin_Amount, TotGefactgoederen T_Fin_Amount, Verzonden int
,TotaalInkord T_Fin_Amount, TotaalInkRgls int,Inkooporder T_Nr_Ord, InkOrdRgl T_LineNR)
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
ISNULL((SELECT SUM(ID.InvDetailAmount)
FROM T_InvoiceDetailDosDet as IDD
inner join T_InvoiceDetail as ID on ID.InvCode=IDD.InvCode and ID.InvLineNr=IDD.InvLinenr
WHERE IDD.DossierCode=DD.Dossiercode AND IDD.DetailCode=DD.Detailcode AND IDD.DetailSubCode=DD.DetailSubcode),0)
AS TotGefactDiensten,
ISNULL((SELECT SUM(ID.InvDetailAmount)
from T_InvoiceDetailShipDet as InvSD
inner join T_ShippingDetail as SD on SD.ShipDocCode=InvSD.ShipDocCode and SD.ShipLineNr=InvSD.ShipLineNr
inner join T_InvoiceDetail as ID on ID.InvCode=InvSD.InvCode and ID.InvLineNr=InvSD.InvLinenr
where SD.DossierCode=DD.Dossiercode AND SD.DetailCode=DD.Detailcode AND SD.DetailSubCode=DD.DetailSubcode),0) as TotGefactgoederen,
ISNULL((select sum(Verz.DelQty)
from dbo.T_DeliveryLine as Verz
where Verz.DossierCode=DD.Dossiercode and Verz.DetailCode=DD.Detailcode and Verz.DetailSubCode=DD.DetailSubcode),0) as Verzonden,
ISNULL((select sum(PDPL.BasicCurrTotalAmount)
from T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine as PDPL on PDPL.PurDocCode=PDL.PurDocCode and PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.DossierCode AND PDL.DetailCode=DD.DetailCode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS TotaalInkord,
ISNULL((select COUNT(PDL.DetailCode)
from T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine as PDPL on PDPL.PurDocCode=PDL.PurDocCode and PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.DossierCode AND PDL.DetailCode=DD.DetailCode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS TotaalInkRgls,
ISNULL((SELECT TOP 1 PD.PurOrdNr FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode),'') AS Inkooporder,
ISNULL((SELECT TOP 1 PDL.PDPartLineNr FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
WHERE DD.DossierCode > N''
select * from #bedragen
drop table #BEDRAGEN
正如您所看到的获取列 TotaalInkord、TotaalInkRgls、Inkooporder、InkOrdRgl 的子查询
使用相同的 from/innerjoin 和 where.
有没有可能把它们结合起来?
如果可以合并会不会更快?
谢谢
背景:
我需要这个 temp-table 来加快存储过程的性能。
这个存储过程是一个很大的 select,它使用许多函数来获取它的列。
这个功能内容我现在已经添加到temptable.
没有样本数据会很困难,但交叉应用应该可以解决问题 - 不能说它是否会表现得更好(虽然应该),你可能需要稍微调整一下。
CREATE TABLE #BEDRAGEN(Dossiercode T_Code_Dossier,Detailcode T_Code_Detail,DetailSubcode T_Code_DetailSub
,Totaalbedrag T_Fin_Amount,TotGefactDiensten T_Fin_Amount, TotGefactgoederen T_Fin_Amount, Verzonden int
,TotaalInkord T_Fin_Amount, TotaalInkRgls int,Inkooporder T_Nr_Ord, InkOrdRgl T_LineNR)
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
sub.TotGefactDiensten,
sub.TotGefactgoederen,
sub.Verzonden,
sub.TotaalInkord,
sub.TotaalInkRgls,
sub.Inkooporder,
sub.InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
cross apply (
SELECT
ISNULL(SUM(ID.InvDetailAmount), 0) as TotGefactDiensten
ISNULL(SUM(ID.InvDetailAmount), 0) as as TotGefactgoederen
ISNULL(sum(Verz.DelQty) ,0) as Verzonden,
ISNULL(sum(PDPL.BasicCurrTotalAmount) ,0) AS TotaalInkord,
ISNULL(COUNT(PDL.DetailCode) ,0) AS TotaalInkRgls,
ISNULL(min(PD.PurOrdNr), '') AS Inkooporder, -- assuming this PD.PurOrdNr is the same for all records of subquery ???
ISNULL(min(PDL.PDPartLineNr),0) AS InkOrdRgl
FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode
) sub
WHERE DD.DossierCode > N''
select * from #bedragen
drop table #BEDRAGEN
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
ISNULL((SELECT SUM(ID.InvDetailAmount)
FROM T_InvoiceDetailDosDet as IDD
inner join T_InvoiceDetail as ID on ID.InvCode=IDD.InvCode and ID.InvLineNr=IDD.InvLinenr
WHERE IDD.DossierCode=DD.Dossiercode AND IDD.DetailCode=DD.Detailcode AND IDD.DetailSubCode=DD.DetailSubcode),0)
AS TotGefactDiensten,
ISNULL((SELECT SUM(ID.InvDetailAmount)
from T_InvoiceDetailShipDet as InvSD
inner join T_ShippingDetail as SD on SD.ShipDocCode=InvSD.ShipDocCode and SD.ShipLineNr=InvSD.ShipLineNr
inner join T_InvoiceDetail as ID on ID.InvCode=InvSD.InvCode and ID.InvLineNr=InvSD.InvLinenr
where SD.DossierCode=DD.Dossiercode AND SD.DetailCode=DD.Detailcode AND SD.DetailSubCode=DD.DetailSubcode),0) as TotGefactgoederen,
ISNULL((select sum(Verz.DelQty)
from dbo.T_DeliveryLine as Verz
where Verz.DossierCode=DD.Dossiercode and Verz.DetailCode=DD.Detailcode and Verz.DetailSubCode=DD.DetailSubcode),0) as Verzonden,
ISNULL(IO.waarde,0) as TotaalInkord,
ISNULL(IO.rgls,0) as TotaalInkRgls,
ISNULL(IO.PurOrdNr,'') as Inkooporder,
ISNULL(IO.PDPartLineNr,'') as InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
Inner Join #StatusType ST on DS.DossierStatusType = ST.StatusType
OUTER APPLY (SELECT top 1 PD.PurOrdNr,PDL.PDPartLineNr,COUNT(PDL.DetailCode) as rgls,sum(PDPL.BasicCurrTotalAmount) as waarde
FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS PDPL ON PDPL.PurDocCode=PDL.PurDocCode AND PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode
GROUP BY PD.PurOrdNr,PDL.PDPartLineNr,PDL.DetailCode,PDPL.BasicCurrTotalAmount) IO
WHERE DD.DossierCode > N''
正在创建以下临时文件-table:
CREATE TABLE #BEDRAGEN(Dossiercode T_Code_Dossier,Detailcode T_Code_Detail,DetailSubcode T_Code_DetailSub
,Totaalbedrag T_Fin_Amount,TotGefactDiensten T_Fin_Amount, TotGefactgoederen T_Fin_Amount, Verzonden int
,TotaalInkord T_Fin_Amount, TotaalInkRgls int,Inkooporder T_Nr_Ord, InkOrdRgl T_LineNR)
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
ISNULL((SELECT SUM(ID.InvDetailAmount)
FROM T_InvoiceDetailDosDet as IDD
inner join T_InvoiceDetail as ID on ID.InvCode=IDD.InvCode and ID.InvLineNr=IDD.InvLinenr
WHERE IDD.DossierCode=DD.Dossiercode AND IDD.DetailCode=DD.Detailcode AND IDD.DetailSubCode=DD.DetailSubcode),0)
AS TotGefactDiensten,
ISNULL((SELECT SUM(ID.InvDetailAmount)
from T_InvoiceDetailShipDet as InvSD
inner join T_ShippingDetail as SD on SD.ShipDocCode=InvSD.ShipDocCode and SD.ShipLineNr=InvSD.ShipLineNr
inner join T_InvoiceDetail as ID on ID.InvCode=InvSD.InvCode and ID.InvLineNr=InvSD.InvLinenr
where SD.DossierCode=DD.Dossiercode AND SD.DetailCode=DD.Detailcode AND SD.DetailSubCode=DD.DetailSubcode),0) as TotGefactgoederen,
ISNULL((select sum(Verz.DelQty)
from dbo.T_DeliveryLine as Verz
where Verz.DossierCode=DD.Dossiercode and Verz.DetailCode=DD.Detailcode and Verz.DetailSubCode=DD.DetailSubcode),0) as Verzonden,
ISNULL((select sum(PDPL.BasicCurrTotalAmount)
from T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine as PDPL on PDPL.PurDocCode=PDL.PurDocCode and PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.DossierCode AND PDL.DetailCode=DD.DetailCode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS TotaalInkord,
ISNULL((select COUNT(PDL.DetailCode)
from T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine as PDPL on PDPL.PurDocCode=PDL.PurDocCode and PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.DossierCode AND PDL.DetailCode=DD.DetailCode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS TotaalInkRgls,
ISNULL((SELECT TOP 1 PD.PurOrdNr FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode),'') AS Inkooporder,
ISNULL((SELECT TOP 1 PDL.PDPartLineNr FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode),0) AS InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
WHERE DD.DossierCode > N''
select * from #bedragen
drop table #BEDRAGEN
正如您所看到的获取列 TotaalInkord、TotaalInkRgls、Inkooporder、InkOrdRgl 的子查询 使用相同的 from/innerjoin 和 where.
有没有可能把它们结合起来? 如果可以合并会不会更快?
谢谢
背景: 我需要这个 temp-table 来加快存储过程的性能。 这个存储过程是一个很大的 select,它使用许多函数来获取它的列。 这个功能内容我现在已经添加到temptable.
没有样本数据会很困难,但交叉应用应该可以解决问题 - 不能说它是否会表现得更好(虽然应该),你可能需要稍微调整一下。
CREATE TABLE #BEDRAGEN(Dossiercode T_Code_Dossier,Detailcode T_Code_Detail,DetailSubcode T_Code_DetailSub
,Totaalbedrag T_Fin_Amount,TotGefactDiensten T_Fin_Amount, TotGefactgoederen T_Fin_Amount, Verzonden int
,TotaalInkord T_Fin_Amount, TotaalInkRgls int,Inkooporder T_Nr_Ord, InkOrdRgl T_LineNR)
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
sub.TotGefactDiensten,
sub.TotGefactgoederen,
sub.Verzonden,
sub.TotaalInkord,
sub.TotaalInkRgls,
sub.Inkooporder,
sub.InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
cross apply (
SELECT
ISNULL(SUM(ID.InvDetailAmount), 0) as TotGefactDiensten
ISNULL(SUM(ID.InvDetailAmount), 0) as as TotGefactgoederen
ISNULL(sum(Verz.DelQty) ,0) as Verzonden,
ISNULL(sum(PDPL.BasicCurrTotalAmount) ,0) AS TotaalInkord,
ISNULL(COUNT(PDL.DetailCode) ,0) AS TotaalInkRgls,
ISNULL(min(PD.PurOrdNr), '') AS Inkooporder, -- assuming this PD.PurOrdNr is the same for all records of subquery ???
ISNULL(min(PDL.PDPartLineNr),0) AS InkOrdRgl
FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS INR ON INR.PurDocCode=PDL.PurDocCode AND INR.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode
) sub
WHERE DD.DossierCode > N''
select * from #bedragen
drop table #BEDRAGEN
INSERT INTO #BEDRAGEN
SELECT DD.DossierCode as Dossiercode,
DD.DetailCode as Detailcode,
DD.DetailSubCode as DetailSubcode,
ISNULL(DBO.SIF_get_SalesAmountDosDetail(DD.Dossiercode,DD.Detailcode,DD.Detailsubcode),0) as Totaalbedrag,
ISNULL((SELECT SUM(ID.InvDetailAmount)
FROM T_InvoiceDetailDosDet as IDD
inner join T_InvoiceDetail as ID on ID.InvCode=IDD.InvCode and ID.InvLineNr=IDD.InvLinenr
WHERE IDD.DossierCode=DD.Dossiercode AND IDD.DetailCode=DD.Detailcode AND IDD.DetailSubCode=DD.DetailSubcode),0)
AS TotGefactDiensten,
ISNULL((SELECT SUM(ID.InvDetailAmount)
from T_InvoiceDetailShipDet as InvSD
inner join T_ShippingDetail as SD on SD.ShipDocCode=InvSD.ShipDocCode and SD.ShipLineNr=InvSD.ShipLineNr
inner join T_InvoiceDetail as ID on ID.InvCode=InvSD.InvCode and ID.InvLineNr=InvSD.InvLinenr
where SD.DossierCode=DD.Dossiercode AND SD.DetailCode=DD.Detailcode AND SD.DetailSubCode=DD.DetailSubcode),0) as TotGefactgoederen,
ISNULL((select sum(Verz.DelQty)
from dbo.T_DeliveryLine as Verz
where Verz.DossierCode=DD.Dossiercode and Verz.DetailCode=DD.Detailcode and Verz.DetailSubCode=DD.DetailSubcode),0) as Verzonden,
ISNULL(IO.waarde,0) as TotaalInkord,
ISNULL(IO.rgls,0) as TotaalInkRgls,
ISNULL(IO.PurOrdNr,'') as Inkooporder,
ISNULL(IO.PDPartLineNr,'') as InkOrdRgl
FROM dbo.T_DossierDetail AS DD
Inner Join dbo.T_Part AS P On P.PartCode = DD.PartCode
Inner Join dbo.T_DossierMain AS DM On DM.DossierCode = DD.DossierCode
Inner Join dbo.T_DossierStatus AS DS On DS.DossierStatusCode = DD.DossierStatusCode
Inner Join #StatusType ST on DS.DossierStatusType = ST.StatusType
OUTER APPLY (SELECT top 1 PD.PurOrdNr,PDL.PDPartLineNr,COUNT(PDL.DetailCode) as rgls,sum(PDPL.BasicCurrTotalAmount) as waarde
FROM T_PurDocPartLineDosDetLink AS PDL
INNER JOIN T_PurchaseDocument as PD on PDL.PurDocCode=PD.PurDocCode
INNER JOIN T_PurDocPartLine AS PDPL ON PDPL.PurDocCode=PDL.PurDocCode AND PDPL.PDPartLineNr=PDL.PDPartLineNr
WHERE PDL.DossierCode=DD.Dossiercode AND PDL.DetailCode=DD.Detailcode AND PDL.DetailSubCode=DD.DetailSubCode
GROUP BY PD.PurOrdNr,PDL.PDPartLineNr,PDL.DetailCode,PDPL.BasicCurrTotalAmount) IO
WHERE DD.DossierCode > N''