วิธีเพิ่ม 1 มิลลิวินาทีในสตริงวันที่และเวลา


15

จากการเลือกฉันสามารถส่งคืนแถว x แบบนี้:

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

เรามีมิลลิวินาทีทั้งหมดที่มี 0

มีวิธีเพิ่ม 1 ต่อ 1 มิลลิวินาทีหรือไม่ดังนั้นการเลือกจะเป็นดังนี้:

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

ฉันกำลังพยายามสร้างเคอร์เซอร์หรือแม้แต่การอัปเดตที่ไม่สำเร็จ

นี่คือแบบสอบถามเพื่อให้ได้ผลลัพธ์ที่ฉันต้องการ:

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

มีค่า 81k DATETIMEสนาม


2
คุณกำลังพยายามเพิ่ม 1 มิลลิวินาทีในแถว 1, 2 มิลลิวินาทีเป็นแถว 2, 3 มิลลิวินาทีในแถว 3 และอื่น ๆ
John Eisbrener

คำตอบ:


33

Datetimeไม่แม่นยำถึงระดับ 1 มิลลิวินาที สิ่งที่คุณขอไม่สามารถกระทำได้เว้นแต่คุณจะเปลี่ยนเป็นประเภทข้อมูลอื่น (เช่นdatetime2)

เอกสาร

คำพูดที่สำคัญ:

ความแม่นยำปัดเศษเป็นความละเอียด 0.000, .003 หรือ .007 วินาที


13

DateAddฟังก์ชั่นคือสิ่งที่คุณกำลังมองหา

ใช้millisecondเป็นพารามิเตอร์แรกของฟังก์ชันเพื่อบอกว่าคุณกำลังเพิ่มมิลลิวินาที จากนั้นใช้1เป็นพารามิเตอร์ตัวที่สองเพื่อเพิ่มจำนวนมิลลิวินาที

นี่คือตัวอย่างการดึงเวลาปัจจุบันลงในตัวแปรแล้วเพิ่มหนึ่งมิลลิวินาทีลงไปและบันทึกผลลัพธ์เป็นตัวแปรตัวที่สองแล้วพิมพ์ตัวแปรแต่ละตัว

Declare @RightNow as DateTime2
Declare @RightNowPlusAMillisecond as DateTime2

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

Print @RightNow
Print @RightNowPlusAMillisecond

ผล:

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

บันทึก:

ฟอร์เรสต์ชี้ให้เห็นคำตอบอื่นdatetimeประเภทข้อมูลไม่รับประกันความแม่นยำเป็นมิลลิวินาที โดยจะปัดเศษขึ้นเป็น .000, .003 หรือ .007 วินาที datetime2หากคุณต้องการความแม่นยำมิลลิวินาทีใช้


13

@ Doug-Dedenมีจุดเริ่มต้นที่ถูกต้อง แต่ฉันแค่อยากลองตอบสิ่งที่ฉันคิดว่าเป็นความตั้งใจดั้งเดิมของคำถาม - วิธีนำไปใช้กับชุดผลลัพธ์ด้วยการเพิ่มมิลลิวินาทีต่อแถว

ในกรณีนี้คุณสามารถใช้ROW_NUMBERและCommon Table Expression (แก้ไขได้ตามต้องการสำหรับโครงสร้างตารางของคุณรวมถึง joins และอื่น ๆ )

เลือกเพื่อแสดงค่า:

;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

อัปเดตเข้าร่วมกลับไปที่ตารางดั้งเดิม:

;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 นี้สามารถอัปเดตได้ Table1ไม่จำเป็นต้องเข้าร่วมกลับไป เพิ่งทำUPDATE CTE SET my_date_column =...
สตีเว่นฮิบเบิล

4

DATETIME2(3)ฉันได้ทำโดยใช้

อย่างที่คุณเห็นในแบบสอบถามด้านล่างมันมีมากขึ้น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)

ป้อนคำอธิบายรูปภาพที่นี่

ความแตกต่างระหว่างdatetimeและdatetime2มีการอธิบายอย่างดีที่นี่

สำหรับแบบฝึกหัดนี้ฉันสร้างตารางชั่วคราวสำหรับการทดสอบและเติมด้วย 999 แตกต่างrandom datesจาก01-jan-2019และวันนี้ ( 23-july-2019)

จากนั้นตามลำดับฉันจะตั้งค่ามิลลิวินาทีจาก 1 ถึง 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

และนี่คือสิ่งที่ฉันได้รับ: (ดูบางส่วน)

ป้อนคำอธิบายรูปภาพที่นี่


2

หนึ่งในโปสเตอร์อื่น ๆ ที่ถูกต้อง; DATETIME(ใน T-SQL) ไม่ถูกต้องกับมิลลิวินาที (ถูกต้องกับหน่วยเป็นมิลลิวินาที)

DATETIME2สำหรับระดับของความถูกต้องที่คุณต้องการใช้

นี่คือตัวอย่างของการแปลงสตริงdatetimeเป็นdatetime2จากนั้นเพิ่ม 1 มิลลิวินาทีและสุดท้ายจะแปลงกลับเป็นสตริง

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

3
กรุณาอย่าระบุvarcharได้โดยไม่ต้องมีความยาว
Aaron Bertrand
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.