เป็นวิธีที่ดีที่สุดในการตัดทอนค่าวันที่และเวลา (เป็นลบชั่วโมงนาทีและวินาที) ใน SQL Server 2008 อะไร
ตัวอย่างเช่น:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
เป็นวิธีที่ดีที่สุดในการตัดทอนค่าวันที่และเวลา (เป็นลบชั่วโมงนาทีและวินาที) ใน SQL Server 2008 อะไร
ตัวอย่างเช่น:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
คำตอบ:
สิ่งนี้ยังคงรวบรวมคะแนนเสียงเพิ่มเติมบ่อยครั้งแม้กระทั่งหลายปีต่อมาและดังนั้นฉันจำเป็นต้องอัปเดตสำหรับ SQL Server รุ่นที่ทันสมัย สำหรับ SQL Server 2008 และใหม่กว่านั้นง่ายมาก:
cast(getDate() As Date)
โปรดทราบว่าสามย่อหน้าสุดท้ายที่อยู่ใกล้ด้านล่างยังคงมีผลบังคับใช้และคุณมักจะต้องย้อนกลับไปและหาวิธีหลีกเลี่ยงการโยนในตอนแรก
แต่ก็มีวิธีอื่นที่จะทำให้สำเร็จเช่นกัน นี่เป็นเรื่องธรรมดาที่สุด
วิธีที่ถูกต้อง (ใหม่ตั้งแต่ SQL Server 2008):
cast(getdate() As Date)
วิธีที่ถูกต้อง (เก่า):
dateadd(dd, datediff(dd,0, getDate()), 0)
นี่เป็นรุ่นเก่าแล้ว แต่ก็ยังคุ้มค่าที่จะรู้เพราะสามารถปรับให้เข้ากับจุดเวลาอื่น ๆ ได้อย่างง่ายดายเช่นช่วงเวลาแรกของเดือนนาทีชั่วโมงหรือปี
วิธีที่ถูกต้องนี้ใช้ฟังก์ชั่นที่บันทึกไว้ซึ่งเป็นส่วนหนึ่งของมาตรฐาน ansi และรับประกันว่าจะทำงานได้ แต่อาจช้าลงบ้าง มันทำงานได้โดยการค้นหาว่ามีกี่วันจากวันที่ 0 ถึงวันที่ปัจจุบันและเพิ่มว่าหลายวันกลับไปวันที่ 0 มันจะทำงานไม่ว่าวิธีการเก็บข้อมูลวันที่ของคุณและไม่ว่าสถานที่ของคุณคืออะไร
วิธีที่รวดเร็ว:
cast(floor(cast(getdate() as float)) as datetime)
สิ่งนี้ใช้ได้เนื่องจากคอลัมน์วันที่และเวลาถูกเก็บเป็นค่าไบนารี่ขนาด 8 ไบต์ โยนพวกมันให้ลอยตั้งพื้นเพื่อเอาเศษและส่วนเวลาของค่าจะหายไปเมื่อคุณส่งกลับไปยังวันที่และเวลา มันเป็นเพียงการขยับเล็กน้อยโดยไม่มีตรรกะที่ซับซ้อนและเป็นอย่างมากรวดเร็ว
โปรดระวังสิ่งนี้ขึ้นอยู่กับรายละเอียดการติดตั้ง Microsoft สามารถเปลี่ยนแปลงได้ตลอดเวลาแม้กระทั่งในการอัพเดทบริการอัตโนมัติ มันยังไม่พกพามาก ในทางปฏิบัติมันไม่น่าเป็นไปได้มากที่การใช้งานนี้จะเปลี่ยนแปลงเร็ว ๆ นี้ แต่ก็ยังมีความสำคัญที่ต้องระวังอันตรายหากคุณเลือกที่จะใช้ และตอนนี้เรามีตัวเลือกที่จะโยนเป็นเดทก็ไม่ค่อยจำเป็น
ทางที่ผิด:
cast(convert(char(11), getdate(), 113) as datetime)
วิธีที่ไม่ถูกต้องทำงานโดยการแปลงสตริงตัดทอนสตริงและแปลงกลับเป็นวันที่และเวลา มันผิดด้วยเหตุผลสองประการ: 1) มันอาจไม่ทำงานในทุก ๆ ที่และ 2) มันเกี่ยวกับวิธีที่ช้าที่สุดในการทำเช่นนี้ ... และไม่ใช่เพียงเล็กน้อย มันเหมือนกับลำดับความสำคัญหรือช้ากว่าตัวเลือกอื่นสองตัว
อัปเดตสิ่งนี้ได้รับการลงคะแนนเมื่อเร็ว ๆ นี้และฉันต้องการเพิ่มลงไปเนื่องจากฉันโพสต์สิ่งนี้ฉันได้เห็นหลักฐานที่ชัดเจนว่าเซิร์ฟเวอร์ SQL จะปรับความแตกต่างของประสิทธิภาพระหว่างวิธี "ถูกต้อง" และ "เร็ว" ซึ่งหมายความว่าคุณควรให้ความโปรดปรานแก่อดีต
ในทั้งสองกรณีคุณต้องการที่จะเขียนคำสั่งของคุณเพื่อหลีกเลี่ยงความจำเป็นที่จะต้องทำเช่นนี้ในสถานที่แรก เป็นเรื่องยากมากที่คุณควรทำงานในฐานข้อมูล
ในสถานที่ส่วนใหญ่ฐานข้อมูลเป็นคอขวดของคุณแล้ว โดยทั่วไปแล้วเซิร์ฟเวอร์ที่แพงที่สุดในการเพิ่มฮาร์ดแวร์ให้กับการปรับปรุงประสิทธิภาพและสิ่งที่ยากที่สุดในการเพิ่มส่วนประกอบเหล่านั้นให้ถูกต้อง (คุณต้องสร้างสมดุลของดิสก์กับหน่วยความจำเป็นต้น) นอกจากนี้ยังเป็นการยากที่สุดในการขยายขอบเขตออกไปทั้งด้านเทคนิคและจากมุมมองทางธุรกิจ ในทางเทคนิคแล้วการเพิ่มเว็บหรือเซิร์ฟเวอร์แอปพลิเคชั่นนั้นง่ายกว่าการใช้เซิร์ฟเวอร์ฐานข้อมูลและแม้ว่ามันจะผิดพลาดก็ตามคุณไม่ต้องจ่าย $ 20,000 + ต่อสิทธิ์ใช้งานเซิร์ฟเวอร์สำหรับ IIS หรือ Apache
ประเด็นที่ฉันพยายามทำคือเมื่อเป็นไปได้คุณควรทำงานนี้ในระดับแอปพลิเคชัน เฉพาะเวลาที่คุณเคยควรพบว่าตัวเองตัดทอน datetime ในโปรแกรม Sql Server คือเมื่อคุณจำเป็นต้องจัดกลุ่มตามวันและแม้แล้วคุณอาจจะมีคอลัมน์พิเศษตั้งค่าเป็นคอลัมน์ที่คำนวณไว้ในเวลาแทรก / ปรับปรุงหรือการบำรุงรักษา ในแอปพลิเคชันตรรกะ รับดัชนีนี้ทำลายซีพียูหนักจากฐานข้อมูลของคุณ
cast(getdate() as date)
?
getdate()
นี่คือการสแตนด์บายสำหรับแหล่งข้อมูลวันที่คุณอาจมี
สำหรับ SQL Server 2008 เท่านั้น
CAST(@SomeDateTime AS Date)
จากนั้นส่งกลับไปที่ datetime ถ้าคุณต้องการ
CAST(CAST(@SomeDateTime AS Date) As datetime)
เพียงเพื่อให้ได้คำตอบที่สมบูรณ์ยิ่งขึ้นนี่เป็นวิธีการทำงานในการตัดส่วนใด ๆ ของวันที่ลงและรวมถึงนาที (แทนที่GETDATE()
ด้วยวันที่จะตัดทอน)
นี่คือความแตกต่างจากคำตอบที่ยอมรับซึ่งคุณสามารถใช้ไม่เพียงdd
(วัน) แต่ส่วนใด ๆ ของวันที่ (ดูที่นี่ ):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
โปรดทราบว่าในนิพจน์ด้านบน0
เป็นวันที่คงที่ในต้นปี (1900-01-01) หากคุณต้องการตัดส่วนที่มีขนาดเล็กลงเช่นวินาทีหรือมิลลิวินาทีคุณจะต้องใช้วันที่คงที่ซึ่งใกล้เคียงกับวันที่จึงจะถูกตัดทอนเพื่อหลีกเลี่ยงการล้น
dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
ตัวอย่างที่ฉันพบบนเว็บเมื่อฉันต้องทำคือ:
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
DateAdd(dd, DateDiff(...), 0)
ด้วย สิ่งนี้อาจกัดคุณได้หากคุณไม่ระวัง
ใน SQl 2005 ฟังก์ชัน trunc_date ของคุณสามารถเขียนได้เช่นนี้
(1)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
วิธีแรกนั้นสะอาดกว่ามาก ใช้การเรียกเมธอดเพียง 3 ครั้งเท่านั้นรวมถึง CAST สุดท้าย () และไม่มีการต่อสตริงซึ่งเป็นการบวกอัตโนมัติ ยิ่งกว่านั้นไม่มีการฉายขนาดใหญ่ที่นี่ หากคุณสามารถจินตนาการได้ว่าสามารถแสดงวันที่ / เวลาได้การแปลงจากวันที่เป็นตัวเลขและกลับเป็นวันที่เป็นกระบวนการที่ค่อนข้างง่าย
(2)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CONVERT(varchar, @date,112)
END
หากคุณกังวลเกี่ยวกับการใช้ชุดข้อมูล (2) หรือ (3) ของไมโครซอฟท์อาจไม่เป็นไร
(3)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END
ประการที่สามวิธีการ verbose มากขึ้น สิ่งนี้ต้องแบ่งวันที่ออกเป็นส่วนปีเดือนและวันรวมกันในรูปแบบ "yyyy / mm / dd" จากนั้นส่งกลับไปที่วันที่ วิธีนี้เกี่ยวข้องกับการเรียกใช้เมธอด 7 ครั้งรวมถึง CAST สุดท้าย () ไม่ต้องพูดถึงการต่อสตริง
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
เลือก cast (floor (cast (getdate () เป็น float)) เป็น datetime) อ้างอิงสิ่งนี้: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html
สำหรับบรรดาของคุณที่มาที่นี่กำลังมองหาวิธีตัดทอนเขตข้อมูล DATETIME ให้เป็นบางสิ่งที่น้อยกว่าทั้งวันตัวอย่างเช่นทุกนาทีคุณสามารถใช้สิ่งนี้:
SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)
ดังนั้นหากวันนี้เป็นวัน2010-11-26 14:54:43.123
นี้ก็จะกลับมา2010-11-26 14:54:00.000
แล้วนี้จะกลับมา
ในการเปลี่ยนช่วงเวลาที่เปลี่ยนไปเป็น 1440.0 ให้แทนที่ด้วยจำนวนช่วงเวลาในหนึ่งวันเช่น
24hrs = 24.0 (for every hour)
24hrs / 0.5hrs = 48.0 (for every half hour)
24hrs / (1/60) = 1440.0 (for every minute)
(วาง.0
ท้ายเสมอเพื่อโยนทิ้งโดยปริยาย)
สำหรับคนที่คุณสงสัยว่าการ(3.0/86400000)
คำนวณของฉันคืออะไร SQL Server 2005 ดูเหมือนจะไม่ถูกFLOAT
นำไปใช้DATETIME
อย่างแม่นยำดังนั้นจึงเพิ่ม 3 มิลลิวินาทีก่อนที่จะปูพื้น
datetime2
ชนิดข้อมูล
แบบสอบถามนี้ควรให้ผลลัพธ์เทียบเท่ากับtrunc(sysdate)
ใน Oracle
SELECT *
FROM your_table
WHERE CONVERT(varchar(12), your_column_name, 101)
= CONVERT(varchar(12), GETDATE(), 101)
หวังว่านี่จะช่วยได้!
นอกจากนี้คุณยังสามารถแยกวันที่using Substring
จากตัวแปรวันที่และการส่งกลับไปยังวันที่และเวลาจะไม่สนใจเวลาส่วนหนึ่ง
declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
นอกจากนี้คุณสามารถเข้าถึงบางส่วนของตัวแปร datetime และรวมเข้ากับวันที่สร้างแบบตัดทอนบางสิ่งเช่นนี้:
SELECT cast(DATENAME(year, @Somedate) + '-' +
Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
DATENAME(day, @Somedate)
as datetime)
ออราเคิล:
TRUNC(SYSDATE, 'MONTH')
เซิร์ฟเวอร์ SQL:
DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)
สามารถใช้ในการตัดทอนนาทีหรือชั่วโมงจากวันที่ในทำนองเดียวกัน
คุณสามารถทำได้ (SQL 2008):
ประกาศ @SomeDate date = getdate ()
select @SomeDate
2009-05-28
TRUNC (aDate, 'DD') จะตัดทอนนาทีวินาทีและชั่วโมง
SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php