การจัดเก็บข้อมูลในคอลัมน์เดียวเป็นวิธีที่ต้องการเนื่องจากมีการเชื่อมโยงอย่างแยกไม่ออก จุดในเวลานั้นเป็นข้อมูลชิ้นเดียวไม่ใช่สองชิ้น
วิธีการทั่วไปในการจัดเก็บข้อมูลวันที่ / เวลาที่ใช้ "เบื้องหลัง" โดยผลิตภัณฑ์จำนวนมากคือการแปลงเป็นค่าทศนิยมโดยที่ "วันที่" เป็นส่วนจำนวนเต็มของค่าทศนิยมและ "เวลา" เป็นเศษส่วน ราคา. ดังนั้น 1900-01-01 00:00:00 จะถูกเก็บไว้ที่ 0.0 และ 20 กันยายน 2016 9:34:00 ถูกเก็บไว้เป็น 42631.39861 42631 คือจำนวนวันตั้งแต่ 1900-01-01 .39861 เป็นส่วนของเวลาที่ผ่านไปตั้งแต่เที่ยงคืน อย่าใช้ประเภททศนิยมโดยตรงเพื่อทำสิ่งนี้ใช้ประเภทวันที่ / เวลาที่ชัดเจน จุดของฉันที่นี่เป็นเพียงภาพประกอบ
การจัดเก็บข้อมูลในสองคอลัมน์แยกกันหมายความว่าคุณจะต้องรวมค่าคอลัมน์ทั้งสองเมื่อใดก็ตามที่คุณต้องการดูว่าจุดที่กำหนดในเวลานั้นเร็วหรือช้ากว่าค่าที่เก็บไว้หรือไม่
หากคุณเก็บค่าไว้ต่างหากคุณจะพบกับ "บั๊ก" ที่ตรวจจับได้ยาก ยกตัวอย่างเช่น
IF OBJECT_ID('tempdb..#DT') IS NOT NULL
DROP TABLE #DT;
CREATE TABLE #DT
(
dt_value DATETIME NOT NULL
, d_value DATE NOT NULL
, t_value TIME(0) NOT NULL
);
DECLARE @d DATETIME = '2016-09-20 09:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
SET @d = '2016-09-20 11:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.dt_value >= '2016-07-01 11:00:00';
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.d_value >= CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00');
ในโค้ดข้างต้นเรากำลังสร้างตารางทดสอบเติมข้อมูลด้วยค่าสองค่าจากนั้นทำการสืบค้นแบบง่าย ๆ กับข้อมูลนั้น ครั้งแรกที่SELECT
ส่งกลับทั้งสองแถวอย่างไรก็ตามที่สองSELECT
ส่งกลับเพียงแถวเดียวซึ่งอาจไม่ได้ผลลัพธ์ที่ต้องการ:
วิธีที่ถูกต้องในการกรองช่วงวันที่ / เวลาที่ค่าอยู่ในคอลัมน์ที่ไม่ต่อเนื่องตามที่ระบุโดย @ypercube ในความคิดเห็นคือ:
WHERE dt.d_value > CONVERT(DATE, '2016-07-01') /* note there is no time component here */
OR (
dt.d_value = CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00')
)
หากคุณต้องการแยกองค์ประกอบเวลาเพื่อการวิเคราะห์คุณสามารถพิจารณาเพิ่มคอลัมน์จากการคำนวณยังคงอยู่สำหรับส่วนเวลาของค่า:
ALTER TABLE #DT
ADD dt_value_time AS CONVERT(TIME(0), dt_value) PERSISTED;
SELECT *
FROM #dt;
คอลัมน์ที่คงอยู่นั้นจะสามารถจัดทำดัชนีอนุญาตให้เรียงลำดับอย่างรวดเร็ว ฯลฯ ตามเวลาของวัน
หากคุณกำลังพิจารณาแยกวันที่และเวลาออกเป็นสองฟิลด์เพื่อจุดประสงค์ในการแสดงผลคุณควรตระหนักว่าการจัดรูปแบบควรทำที่ไคลเอ็นต์ไม่ใช่เซิร์ฟเวอร์