使用子选择更快地进行查询

时间:2016-02-26 11:33:38

标签: sql-server tsql pivot sql-subselect

我有以下存储过程,当没有子选择运行时,超快。但是我需要这些子选择的结果来获取我需要的信息。是否有另一种方法可以在不需要这些子查询的情况下获得这些结果,或者是否有任何方法可以使这些子查询更加优化?

USE [macal]
GO
/****** Object:  StoredProcedure [dbo].[APsp_MapaClientesSemanaUmCliente]    Script Date: 26/02/2016 10:56:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER Procedure [dbo].[APsp_MapaClientesSemanaUmCliente] 

@Vendedor varchar(20) = '',
@NoCliente int = 0,
@NoEstab int = 0

AS 


DECLARE @DynamicPivotQuery AS NVARCHAR(MAX);
DECLARE @ColumnName AS NVARCHAR(MAX);

--Get distinct values of the PIVOT Column 
set @ColumnName =   STUFF((
                select ISNULL(@ColumnName + ',','')
                --+',' 
                + QUOTENAME(courses.anomes)
                FROM (SELECT DISTINCT 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,row_number() over (order by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)) row FROM ft where ft.fdata >= DATEADD(week,-11, GETDATE()) 
                group by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)
                ) Courses

                FOR XML PATH('')
                ),1,1,'');

        --      print @columnname

DECLARE @ColumnNameSelect AS NVARCHAR(MAX)

set @ColumnNameSelect = STUFF((
SELECT
',ISNULL('+QUOTENAME(courses.anomes)+',0) AS '+QUOTENAME('S'+ltrim(rtrim(str(courses.row))))
FROM 
(
SELECT DISTINCT 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,row_number() over (order by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)) row FROM ft where ft.fdata >= DATEADD(week,-11, GETDATE())  
group by 'S'+ltrim(rtrim(str(ft.ftano)))+right('0'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2)
) Courses
order by anomes
FOR XML PATH('')
),1,1,'');

 --print @columnnameselect

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
N'SELECT 
nome,
no,
estab,
morada,
telefone,
tlmvl,
contacto,
email,
ZonaVenda,
ZonaDist,
segmento,
classe,
descpp,
esaldo,
plafondseg,
pmr,
ref,
design,
unidade,
uni2,
peso,
u_uncx,
PrecoTab,
Desc1,
Desc2,
Desc4,
Preco,
DataPreco,
media_semana,

' + @ColumnNameSelect + '

FROM 
(
select cl.nome,
ft.no,
ft.estab,
cl.morada,
cl.telefone,
cl.tlmvl,
cl.contacto,
cl.email,
cl.zona ZonaVenda,
cl.u_zonav ZonaDist,
cl.segmento,
cl.classe,
cl.descpp,
cl.esaldo,
cl.U_EPLAFSEG plafondseg,
ltrim(rtrim(str((select
case 
when count(re.restamp) <> 0 then isnull(sum(datediff(dd,cc.datalc,re.procdata)),0) / count(re.restamp) else 0 end 
from    rl (nolock) 
inner   join re (nolock) on re.restamp = rl.restamp 
inner   join cc (nolock) on cc.ccstamp = rl.ccstamp  
inner   join cl (nolock) on cl.no = cc.no 
where cl.no=ft.no and cl.estab=ft.estab and 
re.process = 1 and 
re.procdata >= convert(char(8), dateadd(mm, -12, getdate()), 112)
)))) PMR,
fi.ref,
st.design,
st.unidade,
st.uni2,
st.peso,
st.u_uncx,
isnull((select top 1 fix.epv from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) PrecoTab,
isnull((select top 1 fix.desconto from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc1,
isnull((select top 1 fix.desc2 from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc2,
isnull((select top 1 fix.desc4 from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Desc4,
isnull((select top 1 fix.etiliquido/fix.qtt from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) Preco,
isnull((select top 1 ftx.fdata from fi(nolock) fix,ft(nolock) ftx where fix.ftstamp=ftx.ftstamp and fix.ref=fi.ref and fix.etiliquido>0 and ftx.no=ft.no and ftx.estab=ft.estab and ftx.tipodoc=1 order by ftx.fdata desc,ftx.fno desc),0) DataPreco,
isnull((select avg(mytable.qtt) from
(
select ftx.no,ftx.estab,fix.ref,datepart(week,ftx.fdata) week,sum(case when ftx.tipodoc=3 then -fix.qtt else fix.qtt end) qtt
from ft(nolock) ftx,fi(nolock) fix where ftx.ftstamp=fix.ftstamp and ftx.no=ft.no and ftx.estab=ft.estab and fix.ref=fi.ref
and ftx.tipodoc=1 and ftx.fdata >= DATEADD(week,-11, GETDATE())
group by ftx.no,ftx.estab,fix.ref,datepart(week,ftx.fdata))
mytable
),0)
media_semana,

''S''+ltrim(rtrim(str(ft.ftano)))+right('+'''0'''+'+ltrim(rtrim(str(datepart(week,ft.fdata)))),2) anomes,
fi.qtt 

from fi,ft,st,cl 
where 
fi.ftstamp=ft.ftstamp and fi.ref=st.ref and cl.no=ft.no and cl.estab=ft.estab 
and ft.fdata >= DATEADD(week,-23, GETDATE())
and ft.tipodoc=1 
and fi.qtt<>0
and cl.no='+cast(@NoCliente as nvarchar(10))+'
and cl.estab='+cast(@NoEstab as nvarchar(10))+'
and cl.vendnm like case when '''+@Vendedor+''' = '+'''TODOS'''+' then '+'''%'''+' else '''+@Vendedor+''' end

) p
PIVOT(SUM(qtt) 
      FOR anomes IN (' + @ColumnName + ')) AS PVTTable
      order by ref'

--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery

1 个答案:

答案 0 :(得分:0)

您是否尝试将子查询转换为临时表或表变量?

联接通常非常快,但可能很难,具体取决于表格的结构以及数据集中的行数。