SQL Server: Nhận dữ liệu chỉ trong năm qua


98

Tôi đang viết một truy vấn trong đó tôi phải lấy dữ liệu chỉ cho năm ngoái. Cách tốt nhất để làm việc này là gì?

SELECT ... FROM ... WHERE date > '8/27/2007 12:00:00 AM'

Câu trả lời:


196

Phần sau thêm -1 năm vào ngày hiện tại:

SELECT ... From ... WHERE date > DATEADD(year,-1,GETDATE())

1
Của bạn sạch sẽ hơn nhưng đây là những gì tôi đã có: YEAR (GETDATE ()) - 1
PCPGMR

2
Điều đó trả về cho bạn một con số, không phải ngày tháng, sau đó bạn không thể so sánh nó với một ngày, mà không tính toán năm của ngày đó. Điều này sau đó sẽ trả lại kết quả không chính xác cho ngày 31 Tháng 12 2014 vs 01 Tháng 1 2015 - đó là trong những năm khác nhau, nhưng không phải là một năm xa nhau ...
samjudson

chính xác. Tôi cần phải so sánh số năm theo số năm, vì vậy, ví dụ như từ 2013 đến 2014 vì dữ liệu đến chỉ có năm. Tôi đã không rõ ràng trong bình luận của tôi. Cảm ơn bạn
PCPGMR

Tôi nhận được thông báo lỗi khi chạy truy vấn này ... "FUNCTION DatabaseName.DATEADD không tồn tại" Bất kỳ đề xuất nào?
Marcello Perri

10

Tôi đã tìm thấy trang này khi đang tìm giải pháp giúp tôi chọn kết quả từ một năm dương lịch trước. Hầu hết các kết quả được hiển thị ở trên dường như trả lại các mục từ 365 ngày qua, điều này không phù hợp với tôi.

Đồng thời, nó đã cung cấp cho tôi đủ hướng để giải quyết nhu cầu của mình trong đoạn mã sau - đoạn mã mà tôi đang đăng ở đây cho bất kỳ người nào khác có cùng nhu cầu như tôi và những người có thể xem trang này để tìm kiếm giải pháp.

SELECT .... FROM .... WHERE year(*your date column*) = year(DATEADD(year,-1,getdate()))

Cảm ơn những người ở trên mà giải pháp đã giúp tôi đạt được những gì tôi cần.


7

Chà, tôi nghĩ có điều gì đó còn thiếu ở đây. Người dùng muốn nhận dữ liệu từ năm trước chứ không phải từ 365 ngày qua. Có một chu vi rất lớn. Theo tôi, số liệu của năm ngoái là số liệu của năm 2007 (nếu tôi đang ở năm 2008 bây giờ). Vì vậy, câu trả lời đúng sẽ là:

SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1

Sau đó, nếu bạn muốn hạn chế truy vấn này, bạn có thể thêm một số bộ lọc khác, nhưng luôn tìm kiếm trong năm qua.

SELECT ... FROM ... WHERE YEAR(DATE) = YEAR(GETDATE()) - 1 AND DATE > '05/05/2007'

Điều này sẽ có hiệu suất rất xấu trên bảng lớn, bạn truy vấn sẽ lặp qua tất cả các kỷ lục để đánh giá giá trị năm ngày, nó sẽ là tốt hơn để sử dụng một phạm vi ngày
Adriaan Davel


4

Dễ đọc nhất, IMO:

SELECT * FROM TABLE WHERE Date >
   DATEADD(yy, -1, CONVERT(datetime, CONVERT(varchar, GETDATE(), 101)))

Cái nào:

  1. Nhận ngày giờ hiện tại GETDATE () = # 8/27/2008 10:23 am#
  2. Chuyển đổi thành một chuỗi có định dạng 101 CONVERT (varchar, # 8/27/2008 10:23 am#, 101) = '8/27/2007'
  3. Chuyển đổi thành CHUYỂN ĐỔI datetime (datetime, '8/27/2007') = # 8/27/2008 12:00 SA#
  4. Trừ đi 1 năm DATEADD (yy, -1, # 8/27/2008 12:00 AM#) = # 8/27/2007 12:00 AM#

Có những biến thể với DATEDIFF và DATEADD để giúp bạn có được nửa đêm của ngày hôm nay, nhưng chúng có xu hướng khá khó hiểu (mặc dù tốt hơn một chút về hiệu suất - không phải là điều bạn nhận thấy so với các lần đọc cần thiết để tìm nạp dữ liệu).


2

GETDATE () trả về ngày và giờ hiện tại .

Nếu năm ngoái bắt đầu vào nửa đêm của ngày hiện tại năm ngoái (như trong ví dụ ban đầu), bạn nên sử dụng một cái gì đó như:

DECLARE @start datetime
SET @start = dbo.getdatewithouttime(DATEADD(year, -1, GETDATE())) -- cut time (hours, minutes, ect.) --  getdatewithouttime() function doesn't exist in MS SQL -- you have to write one
SELECT column1, column2, ..., columnN FROM table WHERE date >= @start

0

Các gợi ý khác là tốt nếu bạn có "SQL only".

Tuy nhiên, tôi đề nghị rằng - nếu có thể - bạn tính ngày trong chương trình của mình và chèn nó dưới dạng chuỗi trong truy vấn SQL.

Ít nhất là đối với các bảng lớn (tức là vài triệu hàng, có thể được kết hợp với các phép nối) sẽ cung cấp cho bạn sự cải thiện tốc độ đáng kể vì trình tối ưu hóa có thể hoạt động với điều đó tốt hơn nhiều.


2
Sẽ tốt hơn nếu bạn tạo một chuỗi được tham số hóa và tránh đặt giá trị trong chính chuỗi đó ...
Adriaan Davel

0

đối số cho hàm DATEADD:

DATEADD (*datepart* , *number* , *date* )

datepart có thể là: yy, qq, mm, dy, dd, wk, dw, hh, mi, ss, ms

number là một biểu thức có thể được giải quyết thành một int được thêm vào một phần ngày tháng

date là một biểu thức có thể được phân giải thành giá trị time, date, smalldatetime, datetime, datetime2 hoặc datetimeoffset.


0
declare @iMonth int
declare @sYear varchar(4)
declare @sMonth varchar(2)
set @iMonth = 0
while @iMonth > -12
begin
    set @sYear = year(DATEADD(month,@iMonth,GETDATE()))
    set @sMonth = right('0'+cast(month(DATEADD(month,@iMonth,GETDATE())) as varchar(2)),2)
    select @sYear + @sMonth
    set @iMonth = @iMonth - 1
end

1
Điều này không giải quyết câu hỏi.
Nathan Skerl

Ngoài ra, trong khi vòng nói chung là xấu cho SQL
StingyJack

0

Tôi, giống như @DE White, đã đến đây vì những lý do tương tự nhưng khác với câu hỏi ban đầu. Câu hỏi ban đầu yêu cầu trong 365 ngày qua. Câu trả lời của @ samjudson cung cấp điều đó. Câu trả lời của @DE White trả về kết quả cho năm dương lịch trước.

Truy vấn của tôi hơi khác ở chỗ nó hoạt động cho năm trước và bao gồm cả ngày hiện tại:

SELECT .... FROM .... WHERE year(date) > year(DATEADD(year, -2, GETDATE()))

Ví dụ: vào ngày 17 tháng 2 năm 2017, truy vấn này trả về kết quả từ ngày 1 tháng 1 năm 2016 đến ngày 17 tháng 2 năm 2017


0

Tôi gặp sự cố tương tự nhưng người lập trình trước đó chỉ cung cấp ngày ở định dạng mm-yyyy. Giải pháp của tôi rất đơn giản nhưng có thể hữu ích đối với một số người (tôi cũng muốn đảm bảo rằng các khoảng trắng bắt đầu và kết thúc đã bị loại bỏ):

SELECT ... FROM ....WHERE 
CONVERT(datetime,REPLACE(LEFT(LTRIM([MoYr]),2),'-
','')+'/01/'+RIGHT(RTRIM([MoYr]),4)) >=  DATEADD(year,-1,GETDATE())

0

Vì một số lý do không có kết quả nào ở trên phù hợp với tôi.

Điều này chọn 365 ngày qua.

 SELECT ... From ... WHERE date BETWEEN CURDATE() - INTERVAL 1 YEAR AND CURDATE()

sẽ rất tốt nếu bạn có thể thêm phiên bản của máy chủ MSSQL mà nó hoạt động.
itwasntme
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.