29 февраля по сравнению с 28 февраля предыдущего года - PullRequest
5 голосов
/ 01 марта 2012

У меня есть хранимая процедура, которая извлекает данные и присоединяет прошлогодние данные к дате.Проблема в том, что данные текущего года не имеют к чему присоединиться, потому что не было 29 февраля 2011 года. Кто-нибудь еще сталкивался с этой проблемой?Кто-нибудь есть какие-либо идеи о том, как обойти это?

Вот хранимая процедура:

SELECT 
--b.Date_Rep AS Date_Rep,
SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   

FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) ON DATEADD(yyyy,-1,b.Date_Rep) = a.date_rep --Last year
WHERE (a.Date_Rep BETWEEN DATEADD(year, -1,@StartDate) AND DATEADD(year, -1,@EndDate))

Ответы [ 4 ]

4 голосов
/ 01 марта 2012

Для начала я бы не стал делать предложение where для столбцов таблицы на внешней стороне левого соединения. Попробуйте вместо этого:

SELECT SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
       SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   
FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) 
       ON DATEADD(yyyy,-1,b.Date_Rep) = a.date_rep --Last year
WHERE b.Date_Rep BETWEEN @StartDate AND @EndDate
1 голос
/ 01 марта 2012

Попробуйте использовать FULL OUTER JOIN вместо LEFT JOIN и используйте COALESCE:

SUM(COALESCE(b.AccountsCreatedThisYear, 0)) AS AccountsCreatedThisYearTot и SUM(COALESCE(a.AccountsCreatedThisYear, 0)) AS AccountsCreatedLastYearTot

поэтому вы избегаете значений NULL, если даты не совпадают.

0 голосов
/ 01 марта 2012

29 февраля прошлого года не было, но 1 марта было 365 дней назад, а 28 февраля - 366 дней назад.

SELECT SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
   SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   
FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) 
   ON DATEADD(dd,-365,b.Date_Rep) = a.date_rep --Last year
WHERE b.Date_Rep BETWEEN @StartDate AND @EndDate 

+ 1 Марк Баннистер, когда я использовал его синтаксис

0 голосов
/ 01 марта 2012
    declare @29Feb datetime = convert(datetime,'2012/02/29')
    declare @28Feb datetime = convert(datetime,'2012/02/28')

 select case when 
             dateadd(yy,-1,@29Feb) = dateadd(yy,-1,@28Feb)
             then 1 
             else 0 end

Этот оператор выбора выводит 1, так что на самом деле даты 29 и 28 февраля имеют только одну соответствующую дату в прошлом году, 28 февраля.

Теперь вы делаете сумму за два периода в разные годы, для которых случается, что первый период на 1 день меньше текущего периода.
Как бы кто-то ответил на следующий вопрос:

 "How many accounts have been created in the last year's February and how many this year?" 

Имеет ли значение тот факт, что в одном феврале было 28 дней, а в другом 29? Я не верю, что это февраль, а не дни.

Итак, я вижу две проблемы с этим запросом:

  • В этом году может быть день, когда учетные записи не были созданы, но в прошлом году, за тот же период, некоторые учетные записи создавались, поэтому левое объединение не перехватывает учетные записи в прошлом году
  • Для этого года для двух разных дат 28 и 29 соответствуют только одному дню, 28, поэтому эта сумма суммируется дважды.


 SELECT     (SUM(b.AccountsCreatedThisYear)
    FROM Report2011.dbo.T_Report_01 WITH (NOLOCK) --This year
    WHERE Date_Rep BETWEEN @StartDate and @EndDate ) as AccountsCreatedThisYearTot,

    (SUM(b.AccountsCreatedThisYear)
    FROM Report2011.dbo.T_Report_01 WITH (NOLOCK) -- Last Year
    WHERE Date_Rep BETWEEN DATEADD(year, -1,@StartDate) AND DATEADD(year, -1,@EndDate)) as AccountsCreatedLastYearTot
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...