Ваш желаемый результат содержит только те комбинации года / продукта, которые содержатся в базовой таблице. Это означает, что если все клиенты предыдущего года будут отсутствовать, вы не увидите этого. Пример: продукт B имел 1 покупателя в 2008 году, но не имел покупателя в 2009 году.
Кроме того, у продукта B было 2 клиента в 2007 году и 1 (другой, такой новый) клиент в 2008 году. Ваш желаемый результат показывает NULL в этом случае, но не должен ли он показать 2 отсутствующих клиента (и 1 нового клиента)?
Цифры, похоже, зависят только от года и продукта. Я думаю, что было бы более полезно увидеть всю дельту между предыдущим и текущим годом, то есть количество клиентов, пропавших клиентов и новых клиентов. Это, конечно, будет работать, только если не будет пропущенных лет. Чтобы скрыть дельту между последним записанным годом и следующим годом, я использовал функцию RANK:
WITH
compare ([Year], Product, ThisYearClient, PrevYearClient, LoyalClient) AS (
SELECT ISNULL(this.[Year], prev.[Year]+1)
, ISNULL(this.Product, prev.Product)
, this.Client, prev.Client
, CASE WHEN this.Client = prev.Client THEN this.Client ELSE NULL END
FROM tblProductClient this
FULL JOIN tblProductClient prev
ON this.Product = prev.Product
AND this.Client = prev.Client
AND this.[Year] = prev.[Year]+1
),
totals ([Year], Product, ClientsThisYear, ClientsPrevYear, LoyalClients, R) AS (
SELECT [Year], Product
, COUNT(ThisYearClient)
, COUNT(PrevYearClient)
, COUNT(LoyalClient)
, RANK() OVER (ORDER BY [Year] DESC)
FROM compare
GROUP BY [Year], Product
)
SELECT [Year], Product, ClientsThisYear, ClientsPrevYear, LoyalClients
, ClientsThisYear - LoyalClients AS NewClients
, ClientsPrevYear - LoyalClients AS MissingClients
FROM totals WHERE R > 1
ORDER BY [Year], Product