Abaixo está um procedimento armazenado para contar o número de widgets feitos em um mês. Se nenhum widget for feito, nenhum registro existirá.
O plano de execução mostra uma INNER JOIN
das tabelas M e A, onde na instrução estou fazendo um LEFT OUTER JOIN
.
Eu gostaria de contar o número de widgets feitos em um período de tempo, juntar isso a uma tabela mensal (janeiro a dezembro) e ter os resultados mostrados em um relatório do SSRS. A junção é porque não consigo COUNT
dados que não estão lá. Atualmente estou recebendo:
MonthName Widget Count
February 2
March 3
April 4
May 6
June 5
July 4
August 6
September 2
October 4
November 1
December 2
Gostaria de incluir na lista os meses em que não foram feitos widgets.
Aqui está o código:
DECLARE @OName varchar(50)
DECLARE @Start_Date DATE
DECLARE @End_Date DATE
SET @OName = 'John'
SET @Start_Date = '01/01/2012'
SET @End_Date = '12/31/2012'
SELECT M.[MonthName]
,COUNT(A.[Widget_ID]) AS 'Widget Count'
FROM [Connector].dbo.[Months] AS M
LEFT OUTER JOIN [SERVER].[DATABASE].[dbo].[Widget] AS A
ON MONTH(A.[Widget_Date]) = M.[MonthID]
WHERE (A.[Operator_Name] LIKE '%'+ @OName +'%')
AND A.[PlantID] = '00000001'
AND (
(A.Widget_Date >= @Start_Date AND @End_Date IS NULL)
OR (A.Widget_Datet <= @End_Date AND @Start_Date IS NULL)
OR (A.Widget_Date >= @Start_Date AND A.Widget_Date <= @End_Date)
OR (@Start_Date IS NULL AND @End_Date IS NULL)
GROUP BY M.[MonthName], M.MonthID
ORDER BY M.[MonthID]
Abaixo está o plano de execução para esta consulta.
::UPDATE1:: Acabei de inserir os nomes dos meses nesta tabela. Não consigo alterar a tabela remota.
CREATE TABLE [dbo].[Months](
[MonthID] [smallint] IDENTITY(1,1) NOT NULL,
[MonthName] [varchar](25) NOT NULL,
CONSTRAINT [PK_Months] PRIMARY KEY CLUSTERED ([MonthID] ASC)
)
GO
INSERT INTO [dbo].[Months]
([MonthName])
VALUES
(<MonthName, varchar(25),>)
GO
A tabela "widget" tem mais de 250 campos, o que vai demorar muito para anonimizar.
Seu código diz que você está fazendo um
LEFT OUTER JOIN
, mas você está mesmo? Sua primeiraWHERE
cláusula (bem como cada uma a seguir) filtra linhas para inclusão da tabela externa:Isso transforma seu
LEFT OUTER JOIN
em umINNER JOIN
, quer você queira ou não. Talvez você quisesse mover esses filtros para aON
cláusula.É claro que eu provavelmente removeria a
MONTH()
função não sargável doJOIN
, já que isso forçaria uma verificação completa na tabela remota e a escreveria desta maneira - eliminando também a junção à sua tabela local de meses:Apenas ignore a
m
coluna na saída (você não pode ordená-la sem incluí-la na saída, e não faz sentido ordenar pelo nome).Outra sugestão: não use
'single quotes'
como delimitadores de alias. As formas disso são obsoletas e também fazem com que os alias de coluna pareçam literais de string. Use[square brackets]
em vez disso.