SQL Server - 来自具有相同WHERE子句的多个表的多个计数

时间:2013-01-16 17:45:05

标签: sql sql-server count sum subquery

我需要来自多个表的多个计数,但是所有表都使用相同的表连接并具有相同的where子句。我得到了正确的结果,但是,在一个非常大而缓慢的查询中,我想学习如何改进它。

我必须从表中得到一个计数:

  • Ocorrencias
  • Followups
  • PropostasComerciais
  • PropostasDeLocacao
  • PedidosDeVendas

3 SUM,全部来自PedidosDeVendas表。

所有这些查询加入:   - Empresas   - PedidosDeVendaXItens

并且所有查询都具有相同的WHERE子句:   - 在哪里SolicitanteID = {用户ID} AND数据> ='{初始日期}'和数据< ='{最终日期}'

这是返回我需要的所有结果的查询:

SELECT U.[ID] AS UniqKey, U.NomeCompleto, R.Regiao,    

(SELECT Count(*)    
FROM Ocorrencias O    
INNER JOIN Nomes N ON (O.ClientesID = N.Codigo AND O.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
WHERE O.UsuariosID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey    
AND O.Data >= '2012-12-01 00:00:00' AND O.Data <= '2012-12-31 23:59:59') AS Ocorrencias,    

(SELECT Count(*)    
FROM FollowUp F    
INNER JOIN Nomes N ON (F.ClienteID = N.Codigo AND F.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
WHERE SolicitanteID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey    
AND Data >= '2012-12-01 00:00:00' AND Data <= '2012-12-31 23:59:59') AS FollowUps,    

(SELECT Count(*)    
FROM v_PropostaComercial PC    
INNER JOIN Nomes N ON (PC.ClienteID = N.Codigo AND PC.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
WHERE PC.SolicitanteID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey    
AND PC.Data >= '2012-12-01 00:00:00' AND PC.Data <= '2012-12-31 23:59:59') AS PropostasComerciais,                  

(SELECT Count(*)    
FROM PropostaDeLocacao PL    
INNER JOIN Nomes N ON (PL.ClienteID = N.Codigo AND PL.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
WHERE PL.ResponsavelID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey    
AND PL.Data >= '2012-12-01 00:00:00' AND PL.Data <= '2012-12-31 23:59:59') AS PropostasDeLocacao,    

(SELECT Count(*)    
FROM PedidosDeVenda PV    
INNER JOIN Nomes N ON (PV.ClienteID = N.Codigo AND PV.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
WHERE PV.SolicitanteID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey    
AND PV.Data >= '2012-12-01 00:00:00' AND PV.Data <= '2012-12-31 23:59:59') AS PedidosDeVenda,                   

(SELECT SUM(PVI.Valor)    
FROM PedidosDeVenda PV    
INNER JOIN Empresas N ON (PV.ClienteID = N.Codigo AND PV.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
INNER JOIN PedidosDeVendaXItens PVI ON PVI.PedidoDeVendaID = PV.[ID]    
INNER JOIN Modelos M ON PVI.ProdutoID = M.[ID]    
WHERE PV.SolicitanteID = U.[ID]    
AND MR.ID_Regiao = R.uniqKey
AND PV.Data >= '2012-12-01 00:00:00' AND PV.Data <= '2012-12-31 23:59:59') As TotalPedidosDeVenda,    

(SELECT SUM(PVI.Valor)    
FROM PedidosDeVenda PV    
INNER JOIN Nomes N ON (PV.ClienteID = N.Codigo AND PV.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
INNER JOIN PedidosDeVendaXItens PVI ON PVI.PedidoDeVendaID = PV.[ID]    
INNER JOIN Modelos M ON PVI.ProdutoID = M.[ID]    
WHERE PV.SolicitanteID = U.[ID]    
AND N.TipoEmpresa = 'PU'    
AND PV.ClienteID <> U.ClienteID    
AND MR.ID_Regiao = R.uniqKey    
AND PV.Data >= '2012-12-01 00:00:00' AND PV.Data <= '2012-12-31 23:59:59') As TotalVendasPublicas,    


(SELECT SUM(PVI.Valor)    
FROM PedidosDeVenda PV    
INNER JOIN Nomes N ON (PV.ClienteID = N.Codigo AND PV.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
INNER JOIN PedidosDeVendaXItens PVI ON PVI.PedidoDeVendaID = PV.[ID]    
INNER JOIN Modelos M ON PVI.ProdutoID = M.[ID]    
WHERE PV.SolicitanteID = U.[ID]    
AND N.TipoEmpresa = 'PR'    
AND PV.ClienteID <> U.ClienteID    
AND MR.ID_Regiao = R.uniqKey    
AND PV.Data >= '2012-12-01 00:00:00' AND PV.Data <= '2012-12-31 23:59:59') As TotalVendasPrivadas,    

(SELECT SUM(PVI.Valor)    
FROM PedidosDeVenda PV    
INNER JOIN Nomes N ON (PV.ClienteID = N.Codigo AND PV.SubCadastro = N.SubCadastro)    
INNER JOIN Municipios_Regiao MR ON N.ID_Municipio = MR.ID_Municipio    
INNER JOIN PedidosDeVendaXItens PVI ON PVI.PedidoDeVendaID = PV.[ID]    
INNER JOIN Modelos M ON PVI.ProdutoID = M.[ID]    
WHERE PV.SolicitanteID = U.[ID]    
AND PV.ClienteID = U.ClienteID    
AND MR.ID_Regiao = R.uniqKey    
AND PV.Data >= '2012-12-01 00:00:00' AND PV.Data <= '2012-12-31 23:59:59') As TotalVendasProprias    

FROM Usuarios U    
INNER JOIN Regioes_Usuario RU ON U.[ID] = RU.ID_Usuario    
INNER JOIN Regioes R ON RU.ID_Regiao = R.uniqKey    
WHERE U.Representante = 64        
ORDER BY R.Regiao, U.NomeCompleto;

有什么技巧可以让我的查询更快更短吗?

2 个答案:

答案 0 :(得分:1)

您不应该在主查询内部的select内部进行密集嵌套查询,因为每次嵌套时我都相信每次外部连接都会执行。

而是考虑声明变量并首先分配这些变量。

喜欢

declare @outsidepredicate int, @Count1 int, @Count 2 int;

select @outsidepredicate = value from sharedtable for expressions

select @Count1 = count(*) 
from table1 t (nolock) 
 join table2 tt (nolock) on t.idshared = tt.idshared
where outsidepredicatecolumn = @outsidepredicate

select @Count2 = count(*) 
from table3 t (nolock) 
 join table4 tt (nolock) on t.idshared = tt.idshared
where outsidepredicatecolumn = @outsidepredicate

然后你可以像这样进行常规测试:

select 
    @Count1
,   @Count2
,   valuefrommain
from tableMain m (nolock) 
 join tableSide s (nolock) on m.idshared = s.idshared

答案 1 :(得分:0)

所以,深入研究了查询,我认为最好的办法是减少对同一个表的重新查询。

原谅错字,如果有的话......有趣的是不明白这些名字......

试试这个:

SELECT `id` FROM `table` WHERE `desc1` LIKE "%something%" OR `desc1` LIKE "%something%" OR `desc3` LIKE "%something%" OR `desc4` LIKE "%something%" OR `desc5` LIKE "%something%" OR `desc6` LIKE "%something%"