2010-07-20 30 views
11

Tôi đang làm việc để tạo biểu đồ cho khách hàng của mình và họ muốn nhận tổng số khách hàng trong khoảng thời gian 24 giờ, 3 ngày, 1 tuần, 1 tháng, v.v. Tôi thành thật không phải là tốt nhất với SQL, do đó, tạo ra các truy vấn này không phải là sở trường của tôi.Whats cách nào tốt nhất để có được kết quả trong 24 giờ qua trong T-SQL?

Liên quan đến việc nhận khách hàng trong vòng 24 giờ, tôi đã xem hai câu lệnh "ở đâu" có thể hoạt động, nhưng tôi không chắc đó là điều tốt nhất.

Phiên bản đầu tiên:

WHERE DATEDIFF(hh,CreatedDate,GETDATE())>24 

Version Thứ hai:

WHERE CreatedDate >= DATEADD(HH, -24, GETDATE()) 

Phiên bản đầu tiên tạo ra 21 dòng và lần thứ hai tạo ra 17 dòng (từ tập dữ liệu cùng, tất nhiên) để rõ ràng là một cái chính xác hơn cái kia. Tôi đang nghiêng về phía đầu tiên, nhưng tôi muốn ý kiến ​​của bạn ... xin vui lòng.

Xin cảm ơn, Andrew

+0

Tôi nghĩ rằng 'Ở ĐÂU DATEDIFF (hh, CreatedDate, getdate())> 24' cần phải được' Ở ĐÂU DATEDIFF (hh, CreatedDate, getdate()) <24' –

+1

. ..để chính xác hơn, 'WHERE DATEDIFF (hh, CreatedDate, GETDATE()) <= 24' để khớp với logic của câu lệnh thứ hai :) –

Trả lời

8

Tránh phiên bản đầu tiên. Đầu tiên, vì nó vô hiệu hóa việc sử dụng chỉ mục. Vấn đề thứ hai (chức năng) với phiên bản đầu tiên là, DATEDIFF(HOUR...) trả về tất cả các giá trị dưới 25 giờ. Hãy thử điều này để làm rõ:

SELECT DATEDIFF(HOUR, '2010-07-19 00:00:00', '2010-07-20 00:59:59.99') 
1

Có thể điều này cho mỗi mệnh đề của bạn ở đâu?

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(hh, -24, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(day, -3, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(wk, -1, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(mm, -1, GETDATE) 

Và như flo được đề cập về chỉ mục, chỉ cần đảm bảo bạn đang lập chỉ mục cột CreatedDate của mình.

8

Phiên bản đầu tiên không chính xác.

WHERE DateDiff(hh, CreatedDate, GETDATE()) > 24 

Điều này sẽ trả lại giá trị ở đâu đó từ 23.0001 giờ trước đến 24.9999 giờ trước bởi vì bạn đang tính "vượt qua ranh giới", không phải là khoảng thời gian 24 giờ thực. Hãy xem xét rằng từ 1:59:59 đến 2:00:00 chỉ sau một giây, nhưng DateDiff theo giờ sẽ trả về 1 giờ. Tương tự, 1:00:00 đến 2:59:59 là gần 2 giờ, nhưng DateDiff theo giờ sẽ trả về cùng 1 giờ.

Phiên bản thứ hai là chính xác.

WHERE CreatedDate >= DateAdd(hh, -24, GETDATE()) 

Thêm 24 giờ vào ngày hiện tại sẽ mang lại thời gian chính xác 24,0 giờ trước, đến mili giây. Điều này do đó sẽ trả về 24 giờ dữ liệu.

Ngoài ra, phiên bản đầu tiên sẽ là xấu ngay cả khi nó là những gì bạn muốn vì động cơ sẽ phải thực hiện toán ngày trên mỗi hàng trong toàn bộ bảng, làm cho bất kỳ chỉ mục tiềm năng nào vô ích và tiêu thụ một loạt CPU không cần thiết. Thay vào đó, thực hiện phép toán ở phía đối diện của biểu thức từ tên cột.Để lặp lại logic của biểu hiện đầu tiên của bạn mà không phạt hiệu suất sẽ trông như thế này:

WHERE CreateDate >= DateAdd(hh, DateDiff(hh, 0, GETDATE()) - 24, 0) 

Ví dụ:

  • GetDate() = '20100720 17:52'
  • DateDiff(hh, 0, '20100720 17:52') = 969065
  • DateAdd(hh, 969065 - 24, 0) = '20100719 17:00'

và để chứng minh điều này giống như biểu thức đầu tiên của bạn:

  • DateDiff(hh, '20100719 17:00', '20100720 17:52') = 24
Các vấn đề liên quan