Tôi nghĩ sử dụng toán học datetime gốc sẽ hiệu quả hơn tất cả những điều này khi chuyển đổi qua lại các định dạng chuỗi, ngày tháng và số khác nhau.
DECLARE @julian VARCHAR(6) = '111186';
SELECT DATEADD(YEAR,
100*CONVERT(INT, LEFT(@julian,1))
+10*CONVERT(INT, SUBSTRING(@julian, 2,1))
+CONVERT(INT, SUBSTRING(@julian,3,1)),
DATEADD(DAY, CONVERT(INT,SUBSTRING(@julian, 4, 3))-1,
0));
Kết quả:
===================
2011-07-05 00:00:00
Giả sử dữ liệu này không thay đổi thường xuyên, có thể hiệu quả hơn nhiều nếu thực sự lưu trữ ngày dưới dạng cột được tính toán (đó là lý do tại sao tôi chọn ngày cơ sở là 0
thay vì một số biểu diễn chuỗi, điều này sẽ gây ra các vấn đề về tính xác định khiến cột không được duy trì và có khả năng được lập chỉ mục).
CREATE TABLE dbo.JDEDates
(
JDEDate VARCHAR(6),
GregorianDate AS CONVERT(SMALLDATETIME,
DATEADD(YEAR,
100*CONVERT(INT, LEFT(RIGHT('0'+JDEDate,6),1))
+10*CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6), 2,1))
+CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6),3,1)),
DATEADD(DAY, CONVERT(INT, RIGHT(JDEDate, 3))-1,
0))
) PERSISTED
);
INSERT dbo.JDEDates(JDEDate) SELECT '111186';
SELECT JDEDate, GregorianDate FROM dbo.JDEDates;
Kết quả:
JDEDate GregorianDate
======= ===================
111186 2011-07-05 00:00:00
Ngay cả khi bạn không lập chỉ mục cột, nó vẫn ẩn phép tính xấu xa khỏi bạn, bạn chỉ phải trả khoản đó tại thời điểm ghi, vì nó không khiến bạn thực hiện các hoạt động chức năng tốn kém tại thời điểm truy vấn bất cứ khi nào cột đó được tham chiếu ...