2012-03-01 64 views
5

Tôi có một thủ tục được lưu trữ để lấy dữ liệu và tham gia dữ liệu của năm ngoái vào Ngày. Vấn đề là dữ liệu năm hiện tại không có gì để tham gia vì không có ngày 29 tháng 2 năm 2011. Có ai khác gặp phải vấn đề này không? Bất cứ ai có bất kỳ ý tưởng về cách làm việc xung quanh nó?ngày 29 tháng 2 so với ngày 28 tháng 2 của năm trước

Đây là thủ tục lưu trữ:

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)) 
+0

Tại sao 'LEFT JOIN' khi' WHERE' khoản sẽ buộc nó để trở thành một bên tham gia? 'DATEADD' không thể tạo ngày không hợp lệ, do đó, vấn đề là * * tham gia, nhưng đến ngày" sai "hoặc cái gì? –

+0

sẽ không chỉ so sánh nó với ngày 01 tháng 3 năm ngoái? – Greg

+1

@ J.B. Tôi với J Copper - Bạn đã so sánh 28 năm này với năm ngoái 28 vì vậy không có ngày nào bạn có thể so sánh dữ liệu từ năm thứ 29 này đến năm kia. – Filburt

Trả lời

0
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 

tuyên bố chọn này kết quả đầu ra 1, vì vậy thực sự là ngày 29 tháng 2 và 28 tháng 2 ngày chỉ có một ngày tương ứng trong năm qua, Tháng 28.

Bây giờ bạn đang làm một khoản tiền cho hai giai đoạn trong những năm khác nhau mà nó xảy ra rằng giai đoạn đầu tiên có ít hơn 1 ngày so với giai đoạn hiện tại.
Làm thế nào ai đó sẽ trả lời cho những câu dưới đây:

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

Có vấn đề gì thực tế một tháng hai có 28 ngày và 29 khác? Tôi không tin như vậy, tham chiếu là tháng Hai, không phải là ngày.

Vì vậy, tôi thấy hai vấn đề với truy vấn này:

  • Có thể có một ngày trong năm nay khi không có các tài khoản đã được tạo ra, nhưng trong năm ngoái, trong cùng thời kỳ, một số tài khoản đã làm, vì vậy các bên trái tham gia không bắt những người trong năm ngoái
  • Đối với năm nay cho hai ngày khác nhau, 28 và 29 chỉ tương ứng một ngày, 28 vì vậy, điều này được tổng hợp hai lần.


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 
1

Hãy thử sử dụng một FULL OUTER JOIN thay vì một LEFT JOIN và sử dụng COALESCE:

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

vì vậy bạn tránh được NULL khi những ngày không phù hợp .

4

Đối với người mới bắt đầu, tôi sẽ không thực hiện mệnh đề where trên các cột từ bảng ở bên ngoài của một phép nối trái. Hãy thử điều này, thay vào đó:

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

Vâng, anh ta đã chuyển đổi sự tham gia trái của anh ta sang một bên trong. – HLGEM

0

Không có ngày 29 tháng 2 năm ngoái nhưng ngày 1 tháng 3 là 365 ngày trước và ngày 28 tháng 2 là 366 ngày trước.

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 Đánh dấu Bannister như tôi sử dụng cú pháp của ông

Các vấn đề liên quan