डेटा को एक ही कॉलम में संग्रहीत करना पसंदीदा तरीका है, क्योंकि वे अटूट रूप से जुड़े हुए हैं। समय का एक बिंदु जानकारी का एक टुकड़ा है, दो नहीं।
कई उत्पादों द्वारा "दृश्यों के पीछे" नियोजित दिनांक / समय डेटा को संग्रहीत करने का एक सामान्य तरीका है, इसे एक दशमलव मान में परिवर्तित करके, जहां "दिनांक" दशमलव मान का पूर्णांक भाग है, और "समय" आंशिक है मूल्य। तो, 1900-01-01 00:00:00 को 0.0 और सितंबर 20, 2016 9:34:00 को 42631.39861 के रूप में संग्रहीत किया जाता है। 4-0131 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;
इसके बाद बने कॉलम को समय-समय पर तेजी से हल करने आदि की अनुमति दी जा सकती है।
यदि आप प्रदर्शन उद्देश्यों के लिए दिनांक और समय को दो क्षेत्रों में विभाजित करने पर विचार कर रहे हैं, तो आपको महसूस करना चाहिए कि स्वरूपण क्लाइंट पर किया जाना चाहिए, न कि सर्वर पर।