Làm cách nào để thêm 1 mili giây vào chuỗi datetime?


15

Dựa trên một lựa chọn, tôi có thể trả về x hàng như thế này:

1   2019-07-23 10:14:04.000
1   2019-07-23 10:14:11.000
2   2019-07-23 10:45:32.000
1   2019-07-23 10:45:33.000

Chúng tôi có tất cả mili giây với 0.

Có cách nào để thêm 1 mili giây không, vì vậy phần chọn sẽ như thế này:

1   2019-07-23 10:14:04.001
1   2019-07-23 10:14:11.002
2   2019-07-23 10:45:32.003
1   2019-07-23 10:45:33.004

Tôi đang cố gắng tạo một con trỏ hoặc thậm chí là một bản cập nhật không thành công.

Đây là truy vấn để có được kết quả tôi muốn:

  select top 10 ModifiedOn 
    from [SCHEMA].[dbo].[TABLE]
  where FIELD between '2019-07-23 00:00' and '2019-07-23 23:59'

Có 81k giá trị. Lĩnh vực này là DATETIME.


2
Bạn đang cố gắng thêm 1 mili giây vào hàng 1, 2 mili giây cho hàng 2, 3 mili giây cho hàng 3, v.v.?
John Eisbrener

Câu trả lời:


33

Datetimekhông chính xác đến mức 1 mili giây. Những gì bạn đang yêu cầu là không thể trừ khi bạn thay đổi thành một kiểu dữ liệu khác (tức là datetime2).

Tài liệu

Trích dẫn quan trọng:

Độ chính xác Làm tròn đến số gia của .000, .003 hoặc .007 giây


13

Các DateAddchức năng là những gì bạn đang tìm kiếm.

Sử dụng millisecondlàm tham số đầu tiên cho hàm, để nói với nó rằng bạn đang thêm mili giây. Sau đó sử dụng 1làm tham số thứ hai, cho số mili giây cần thêm.

Dưới đây là một ví dụ, lấy thời gian hiện tại vào một biến và sau đó thêm một mili giây vào nó và lưu kết quả dưới dạng biến thứ hai, sau đó in từng biến

Declare @RightNow as DateTime2
Declare @RightNowPlusAMillisecond as DateTime2

Select @RightNow = Getdate()
Select @RightNowPlusAMillisecond = DateAdd(millisecond,1,@RightNow)

Print @RightNow
Print @RightNowPlusAMillisecond

Các kết quả:

2019-07-23 08:25:38.3500000
2019-07-23 08:25:38.3510000

Ghi chú:

Như Forrest chỉ ra trong một câu trả lời khác, datetimekiểu dữ liệu không đảm bảo độ chính xác đến mili giây. Nó làm tròn đến số gia .000, .003 hoặc .007 giây. Nếu bạn muốn độ chính xác mili giây, sử dụng datetime2.


13

@ Doug-Deden có điểm bắt đầu đúng, nhưng tôi chỉ muốn cố gắng trả lời những gì tôi nghĩ là mục đích ban đầu của câu hỏi - làm thế nào để áp dụng nó vào tập kết quả với mức tăng mili giây trên mỗi hàng.

Trong trường hợp đó, bạn có thể sử dụng ROW_NUMBERBiểu thức bảng chung (chỉnh sửa khi cần cho cấu trúc bảng của bạn, bao gồm các phép nối, v.v.).

Chọn để hiển thị giá trị:

;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
SELECT TOP 1000 *, DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2)) [new_date]
FROM CTE
ORDER BY my_date_column

Cập nhật tham gia trở lại bảng gốc:

;WITH CTE AS (
SELECT t.my_id, t.my_date_column, ROW_NUMBER() OVER (ORDER BY my_date_column, my_id DESC) AS R
FROM Table1 t
)
UPDATE t SET 
my_date_column = DATEADD(MILLISECOND, R, CAST(my_date_column AS datetime2))
FROM CTE c
     JOIN Table1 t ON c.my_id = t.my_id

CTE này có thể cập nhật. Không cần phải tham gia trở lại Table1. Chỉ cần làmUPDATE CTE SET my_date_column =...
Steven Hibble

4

Tôi đã thực hiện nó bằng cách sử dụng DATETIME2(3).

Như bạn có thể thấy trên truy vấn bên dưới, nó là nhiều hơn economic:

declare @dt1 datetime2(3)
declare @dt2 datetime2

SELECT @DT1 = SYSDATETIME()
SELECT @DT2=  SYSDATETIME()

SELECT [THE LENGTH OF DATETIME2]=DATALENGTH(@DT2)
      ,[THE LENGTH OF DATETIME2(3)]=DATALENGTH(@DT1)

nhập mô tả hình ảnh ở đây

Sự khác biệt giữa datetimedatetime2được giải thích tốt ở đây .

Đối với bài tập này, tôi tạo một bảng tạm thời cho mục đích thử nghiệm và điền vào đó với 999 khác nhau random datestừ 01-jan-2019và ngày nay ( 23-july-2019)

và sau đó theo thứ tự, tôi đặt mili giây từ 1 đến 999

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOEXEC OFF

IF OBJECT_ID ('TEMPDB..#T1') IS NOT NULL
   DROP TABLE #T1

CREATE TABLE #t1(the_date DATETIME2(3) NOT NULL PRIMARY KEY CLUSTERED )
GO

-- run this 999 times - hopefully there will be no duplicates
-- SELECT 204*24*60*60 - today is 23-july-2019 - the 203rd day of the year
    DECLARE @DT DATETIME2(3)
    SELECT @DT = CONVERT(DATETIME2(3),
           DATEADD(SECOND, ABS(CHECKSUM(NEWID()) % 17625600), 
                   '2019-01-01'),120) 

    --SELECT @DT

    IF NOT EXISTS( SELECT 1 FROM #T1 WHERE THE_DATE = @DT) 
    INSERT INTO #T1 VALUES (@DT)
GO 999


--check it out what we have
SELECT * FROM #T1

--get the date and the new date
SELECT 
 THE_DATE
,THE_NEW_DATE= DATEADD(MILLISECOND, ROW_NUMBER() OVER (ORDER BY THE_DATE), THE_DATE ) 
 FROM #T1

và đây là những gì tôi nhận được: (xem một phần)

nhập mô tả hình ảnh ở đây


2

Một trong những áp phích khác là chính xác; DATETIME(trong T-SQL) không chính xác đến mili giây (nó chính xác đến centisecond).

Đối với mức độ chính xác, bạn muốn sử dụng DATETIME2.

Dưới đây là một ví dụ về chuyển đổi một chuỗi datetimethành datetime2, sau đó thêm 1 mili giây và cuối cùng, chuyển đổi lại thành chuỗi.

select convert(
            varchar(MAX), --in T-SQL, varchar length is optional
            dateadd(
                millisecond,
                1,
                convert(
                    datetime2,
                    '2019-07-23 12:01:23.11'
                )
            )
        )

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.