मैं SQL सर्वर में डेटाइम को कैसे काट सकता हूं?


280

SQL Server 2008 में डेटाइम मान (घंटे और सेकंड निकालने के लिए) को काट देने का सबसे अच्छा तरीका क्या है?

उदाहरण के लिए:

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000

जवाबों:


494

यह अक्सर अतिरिक्त वोटों को इकट्ठा करना जारी रखता है, यहां तक ​​कि कई साल बाद भी, और इसलिए मुझे इसे एसक्यूएल सर्वर के आधुनिक संस्करणों के लिए अपडेट करने की आवश्यकता है। Sql सर्वर 2008 और बाद के लिए, यह सरल है:

cast(getDate() As Date)

ध्यान दें कि नीचे के पास पिछले तीन पैराग्राफ अभी भी लागू होते हैं, और आपको अक्सर एक कदम वापस लेने और पहली जगह में कलाकारों से बचने का एक तरीका खोजना होगा।

लेकिन इसे पूरा करने के अन्य तरीके भी हैं। यहाँ सबसे आम हैं।

सही तरीका (Sql सर्वर 2008 के बाद से नया):

cast(getdate() As Date)

सही तरीका (पुराना):

dateadd(dd, datediff(dd,0, getDate()), 0)

यह अब पुराना है, लेकिन यह अभी भी जानने लायक है क्योंकि यह आसानी से अन्य समय बिंदुओं के लिए भी अनुकूल हो सकता है, जैसे कि महीने का पहला क्षण, मिनट, घंटा या वर्ष।

यह सही तरीका प्रलेखित फ़ंक्शंस का उपयोग करता है जो एएनआई मानक का हिस्सा हैं और काम करने की गारंटी है, लेकिन यह कुछ हद तक धीमा हो सकता है। यह यह पता लगाकर काम करता है कि दिन 0 से वर्तमान दिन तक कितने दिन हैं, और उस दिन को वापस जोड़कर 0. दिन तक। यह इस बात से कोई फर्क नहीं पड़ता है कि आपका डेटटाइम कैसे संग्रहीत किया जाता है और आपका लोकेशन क्या है।

तेज़ तरीका:

cast(floor(cast(getdate() as float)) as datetime)

यह काम करता है क्योंकि डेटाटाइम कॉलम को 8-बाइट बाइनरी मान के रूप में संग्रहीत किया जाता है। उन्हें फ़्लोट करने के लिए कास्ट करें, अंश को हटाने के लिए उन्हें फ़्लोर करें, और मानों का समय भाग तब समाप्त हो जाता है जब आप उन्हें वापस डेटाइम में डालते हैं। यह सब कोई जटिल तर्क के साथ थोड़ा सा बदलाव है और यह बहुत तेज़ है।

ध्यान रखें यह एक कार्यान्वयन विवरण पर निर्भर करता है Microsoft किसी भी समय, यहां तक ​​कि एक स्वचालित सेवा अपडेट में भी बदलने के लिए स्वतंत्र है। यह भी बहुत पोर्टेबल नहीं है। व्यवहार में, यह बहुत ही संभावना नहीं है कि यह कार्यान्वयन जल्द ही किसी भी समय बदल जाएगा, लेकिन यदि आप इसका उपयोग करना चुनते हैं, तो खतरे से अवगत होना अभी भी महत्वपूर्ण है। और अब जबकि हमारे पास तारीख के रूप में कास्ट करने का विकल्प है, यह शायद ही कभी आवश्यक है।

गलत रास्ता:

cast(convert(char(11), getdate(), 113) as datetime)

गलत तरीके से एक स्ट्रिंग में परिवर्तित करके, स्ट्रिंग को काटकर, और एक डेटाइम में परिवर्तित करके काम करता है। यह गलत है , दो कारणों से: 1) यह सभी स्थानों पर काम नहीं कर सकता है और 2) यह ऐसा करने के सबसे धीमे संभव तरीके के बारे में है ... और न केवल थोड़ा; यह अन्य विकल्पों की तुलना में परिमाण के क्रम या दो धीमे की तरह है।


अपडेट यह हाल ही में कुछ वोटों को मिल रहा है, और इसलिए मैं इसे जोड़ना चाहता हूं कि जब से मैंने यह पोस्ट किया है मैंने कुछ बहुत ठोस सबूत देखे हैं कि एसक्यूएल सर्वर "सही" तरीके और "तेज" तरीके के बीच प्रदर्शन अंतर को अनुकूलित करेगा। , मतलब अब आपको पूर्व का पक्ष लेना चाहिए।

या तो मामले में, आप पहली बार ऐसा करने की आवश्यकता से बचने के लिए अपने प्रश्नों को लिखना चाहते हैं । यह बहुत दुर्लभ है कि आपको डेटाबेस पर यह काम करना चाहिए।

ज्यादातर जगहों पर, डेटाबेस पहले से ही आपकी अड़चन है। यह आम तौर पर सर्वर है जो प्रदर्शन सुधार के लिए हार्डवेयर जोड़ने के लिए सबसे महंगा है और उन परिवर्धन को सही करने के लिए सबसे कठिन है (उदाहरण के लिए, आपको मेमोरी के साथ डिस्क को संतुलित करना होगा)। यह तकनीकी रूप से और व्यावसायिक दृष्टि से, बाहर की ओर स्केल करने के लिए सबसे कठिन है; डेटाबेस सर्वर की तुलना में वेब या एप्लिकेशन सर्वर को जोड़ना तकनीकी रूप से बहुत आसान है और यहां तक ​​कि अगर आप झूठे थे तो आप IIS या अपाचे के लिए $ 20,000 + प्रति सर्वर लाइसेंस का भुगतान नहीं करते हैं।

मैं जिस बिंदु को बनाने की कोशिश कर रहा हूं वह यह है कि जब भी संभव हो आपको यह काम आवेदन स्तर पर करना चाहिए। केवल समय आप कभी भी अपने आप को खोजना चाहिए Sql सर्वर पर एक datetime छोटा है जब आप को बनाए रखा दिन के अनुसार समूहबद्ध करने की जरूरत है, और फिर भी आप शायद एक अतिरिक्त स्तंभ एक गणना स्तंभ के रूप में स्थापित, सम्मिलित / अपडेट समय पर बनाए रखा होना चाहिए, या है आवेदन तर्क में। अपने डेटाबेस से यह इंडेक्स-ब्रेकिंग, सीपीयू-भारी काम करें।


6
"फास्ट तरीका" अभी भी सबसे तेज़ तरीका है sql 2008 के लिए एक बेंचमार्क के अनुसार मैं सिर्फ भाग गया
सैम भगवा

3
FYI करें: stackoverflow.com/q/1177449/27535 और stackoverflow.com/q/133081/27535 डेटाडेट / डेडिफ़ "जीत ..."। एक एकल चर के लिए, जो निश्चित रूप से परवाह करता है, और एक उम्मीद करता है कि आपने एक लाख पंक्तियों पर कॉलम या इस तरह की गणना की है :-)
gbn

9
यह "सही" तरीका केवल आकस्मिक रूप से काम करता है। जिस तरह से लिखा गया है वह ऐसा है मानो DateAdd के लिए सिंटैक्स (अंतराल, तिथि, वेतन वृद्धि) थे, लेकिन यह नहीं है। यह (अंतराल, वृद्धि, तिथि) है। जब मैं महीने के पहले को डेट करने की कोशिश करता हूं तो मैं इस पर अड़ जाता हूं: SELATE DATEADD (m, 0, DatedIFF (m, 0, GETDATE ())) काम नहीं करता, लेकिन SELATE DATEADD (m, DatedIFF (m,) 0, GETDATE ()), 0) करता है। कम से कम, यह वही है जो मैं 2008R2 में देखता हूं।
केली क्लाइन

1
@Kelly 2008R2 में, सिर्फ क्यों नहीं cast(getdate() as date)?
जोएल कोएहॉर्न

2
वे सभी डेटाइम कॉलम पर काम करते हैं। getdate()यहाँ एक स्टैंड-इन है जो कुछ भी आप के पास हो सकता है।
जोएल कोएहॉर्न

44

SQL Server 2008 के लिए ही

CAST(@SomeDateTime AS Date) 

फिर अगर आप चाहें तो इसे वापस डाइमटाइम पर डाल सकते हैं

CAST(CAST(@SomeDateTime AS Date) As datetime)

अच्छा बिंदु: मैं अभी भी 2005 पर हूं और 2008 के लिए यह शायद नया "सही" तरीका है और यहां तक ​​कि "तेज" तरीके के प्रदर्शन से मेल खा सकता है।
जोएल कोएहॉर्न

1
इस नए तरीके का प्रदर्शन "तेज" तरीके से भी तेज है।
ErikE

21

बस एक और अधिक पूर्ण उत्तर के लिए, यहाँ किसी भी तिथि भाग को नीचे और मिनटों सहित बदलने के लिए एक काम करने का तरीका है ( GETDATE()तिथि को कम करने के लिए बदलें )।

यह उस स्वीकृत उत्तर से अलग है जिसमें आप न केवल dd(दिनों) का उपयोग कर सकते हैं , बल्कि तारीख के किसी भी भाग ( यहाँ देखें ):

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

ध्यान दें कि ऊपर की अभिव्यक्ति में, 0एक वर्ष की शुरुआत (1900-01-01) की निरंतर तारीख है। यदि आपको छोटे भागों में विभाजित करने की आवश्यकता है, जैसे कि सेकंड या मिलीसेकंड, तो आपको एक निरंतर तारीख लेने की आवश्यकता है जो अतिप्रवाह से बचने के लिए छोटा होने की तारीख के करीब है।


1
यह राक्षसी रूप से सहायक था। मैंने पूरे दिन की तुलना में कम जगह पर तारीख-समय को कम करने के लिए सभी तरह से देखा।
माइकल - जहां

1
@ माइकल, प्रतिक्रिया के लिए धन्यवाद, यह जानकर अच्छा लगा कि इससे आपको मदद मिली!
लूसेरो

1
+1 यह अधिक उत्थान होना चाहिए, यह एक बढ़िया उत्तर है जो चयनित उत्तर पर विस्तृत है।
जटेट

1
बस इतना है कि इंटरनेट जानता है, आप पूर्ण तिथि अवधि तक सीमित नहीं है। पूर्णांक विभाजन का उपयोग करते हुए, 15 मिनट के अंतराल के लिए एक उदाहरण दिया गया है:dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
माइकल - व्हेयर क्ले शिर्की

7

स्निपेट मुझे वेब पर मिला जब मुझे ऐसा करना पड़ा:

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))

मैं 2005 में हूं, लेकिन मैंने सोचा कि 2008 में इसके लिए कुछ नया कार्य था ??
के.एम.

2
साफ! मैं डेटापार्ट्स को विभाजित करने और उन्हें वापस एक साथ रखने के लिए स्ट्रिंग हैंडलिंग का उपयोग कर सकता था। प्रासंगिक नहीं हो सकता है, लेकिन SQL2008 में एक समय तत्व के बिना एक शुद्ध दिनांक-केवल डेटा प्रकार है।
Frans

1
और ध्यान दें कि आपके पास DateAdd ऑपरेंड मिश्रित है, यह है DateAdd(dd, DateDiff(...), 0)। यदि आप सावधान नहीं हैं तो यह आपको काट सकता है।
एरिक

1

SQl 2005 में आपके trunc_date फ़ंक्शन को इस तरह लिखा जा सकता है।

(1)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
    CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END

पहली विधि बहुत अधिक क्लीनर है। यह अंतिम CAST () सहित केवल 3 विधि कॉल का उपयोग करता है और कोई स्ट्रिंग संघनन नहीं करता है, जो एक स्वचालित प्लस है। इसके अलावा, यहां कोई विशाल प्रकार की जातियां नहीं हैं। यदि आप कल्पना कर सकते हैं कि दिनांक / समय टिकटों का प्रतिनिधित्व किया जा सकता है, तो तारीखों से संख्याओं में और तारीखों में परिवर्तित करना एक काफी आसान प्रक्रिया है।

(2)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
      SELECT CONVERT(varchar, @date,112)
END

यदि आप Microsoft के डेटाटाइम्स (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

तीसरा, अधिक क्रिया विधि। इसके लिए इसके वर्ष, महीने और दिन के हिस्सों में तारीख को तोड़ना, उन्हें "य्य / मिमी / डीडी" प्रारूप में एक साथ रखना, फिर उस तारीख को वापस लाना होगा। इस विधि में अंतिम CAST () सहित 7 विधि कॉल शामिल हैं, न कि स्ट्रिंग समाकलन का उल्लेख करने के लिए।



0

(दिनांक के रूप में नाव के रूप में मंजिल (डाली (getdate ()))) कलाकारों का चयन इस संदर्भ: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html


फ्लोटिंग और बैक टू डेटटाइम के लिए कास्टिंग सही तरीके से काम नहीं करता है
एरिक

0

आप में से जो लोग यहां आए थे, वे पूरे दिन के लिए कुछ समय के लिए एक 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 मिलीसेकंड जोड़ता है।


1
फ़्लोटिंग पॉइंट प्रिसिजन लिमिट्स के कारण राउंडिंग एरर से सावधान रहें ... हालाँकि, यह datetime2डेटा प्रकार के साथ काम नहीं करता है ।
लुसिरो

घंटे के लिए, DATEADD का चयन करें (घंटे, DatedIFF (घंटा, 0, GETDATE ()), 0) काम करता है, भी। मिनट भी, लेकिन दूसरा एक अतिप्रवाह में परिणाम देगा।
केली क्लाइन

फ्लोटिंग और बैक टू डेटटाइम के लिए कास्टिंग सही तरीके से काम नहीं करता है
एरिक

0

यह क्वेरी आपको trunc(sysdate)ओरेकल के समकक्ष परिणाम देनी चाहिए ।

SELECT  * 
FROM    your_table
WHERE   CONVERT(varchar(12), your_column_name, 101)
      = CONVERT(varchar(12), GETDATE(), 101)

उम्मीद है की यह मदद करेगा!


0

आप using Substringडेटाइम चर से तारीख भी निकाल सकते हैं और वापस डेटाइम पर कास्टिंग समय भाग की उपेक्षा करेंगे।

declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime) 

इसके अलावा, आप डेटाटाइम चर के कुछ हिस्सों तक पहुंच सकते हैं और उन्हें एक निर्माणित तिथि में विलय कर सकते हैं, कुछ इस तरह से:

SELECT cast(DATENAME(year, @Somedate) + '-' + 
       Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
       DATENAME(day, @Somedate) 
       as datetime)

0

आकाशवाणी:

TRUNC(SYSDATE, 'MONTH')

एस क्यू एल सर्वर:

DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)

इसी तरह एक तिथि से मिनट या घंटों को काट-छाँट के लिए इस्तेमाल किया जा सकता है।



हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.