SQL सर्वर में डेटाइम का समय भाग निकालने के लिए सबसे अच्छा तरीका


514

SQL सर्वर में डेटाइम फ़ील्ड से समय भाग को निकालते समय कौन सी विधि सर्वश्रेष्ठ प्रदर्शन प्रदान करती है?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

या

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

दूसरी विधि या तो कुछ और बाइट्स भेजती है, लेकिन रूपांतरण की गति जितनी महत्वपूर्ण नहीं हो सकती है।

दोनों भी बहुत तेज दिखाई देते हैं, लेकिन सैकड़ों-हजारों या अधिक पंक्तियों के साथ काम करते समय गति में अंतर हो सकता है?

इसके अलावा, क्या यह संभव है कि एसक्यूएल में डेटाइम के समय के हिस्से से छुटकारा पाने के लिए और भी बेहतर तरीके हैं?


1
मैंने अपने प्रोडक्शन टेबल में एक मिलियन रिकॉर्ड पर इसे आज़माया है और मुझे किसी भी तरह से प्रदर्शन पर एक सटीक रीडिंग नहीं मिली है। दोनों विधियों ने हालांकि डेटा की सटीक समान मात्रा वापस कर दी।
स्टीफन पेरेलसन

9
18,000,000 पंक्तियों पर यह वही है जो मैंने पाया है (SQL Server 2008): विधि b विधि की तुलना में लगभग 24% धीमी है। CAST (FLOOR (CAST (getdate) AS AS FLOAT)) AS DATETIME) विधि की तुलना में 3.5% धीमा है। विधि प्रदर्शन के संबंध में एक विजेता प्रतीत होती है। सभी महान जवाब के लिए धन्यवाद।
स्टीफन पेरेल्सन

46
क्यों बिल्ली एसक्यूएल एक अंतर्निहित समारोह में यह करने के लिए वैसे भी नहीं है? !!
गैरी मैकगिल

10
SQL 2008 का नया DATE डेटाटाइप इसे संभाल लेगा।
फिलिप केली

जवाबों:


557

कड़ाई से, विधि aकम से कम संसाधन गहन है:

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

उसी अवधि के लिए कम CPU को एक ही समय में एक लाख पंक्तियों के लिए गहन साबित करें, जिस तरह से उनके हाथों पर बहुत अधिक समय होता है: SQL सर्वर में सबसे प्रभावी तरीका दिनांक + समय से तारीख पाने के लिए?

मैंने इसी तरह के परिणामों के साथ भी एक समान परीक्षण कहीं और देखा।

मुझे DATEADD / DatedIFF पसंद है क्योंकि:

संपादित करें, अक्टूबर 2011

SQL Server 2008+ के लिए, आप CAST से dateयानी कर सकते हैं CAST(getdate() AS date)। या बस dateडेटाटाइप का उपयोग करें ताकि हटाने का समय न हो।

संपादित करें, जनवरी 2012

यह कितना लचीला है, इसका एक काम किया गया उदाहरण: एसक्यूएल सर्वर में राउंडेड टाइम या डेट फिगर द्वारा गणना करने की आवश्यकता है

संपादित करें, मई 2012

बिना सोचे-समझे WHERE क्लॉज़ और लाइक में इसका इस्तेमाल न करें: किसी फ़ंक्शन को जोड़ने या किसी स्तंभ पर CAST को इंडेक्स का उपयोग अमान्य करता है। नंबर 2 यहां देखें: http://www.simple-talk.com/sql/t-sql-programming/ten-common-sql-programming-mistakes/

अब, इसका एक उदाहरण बाद में SQL सर्वर ऑप्टिमाइज़र संस्करण है, जो CAST को सही ढंग से प्रबंधित कर रहा है, लेकिन आम तौर पर यह एक बुरा विचार होगा ...

डेटाटाइम 2 के लिए संपादित करें, सितंबर 2018

DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2epoch datetime2 = '19000101'

select DATEADD(dd, DATEDIFF(dd, @datetime2epoch, @datetime2value), @datetime2epoch)

3
2011 के अक्टूबर के संपादन के लिए @ डेविड सोकोको फिर कोड होगा: चयन करें (तिथि के अनुसार () तिथि)
चोको स्मिथ

1
SQL के अधिक हाल के संस्करणों के लिए, डेटटाइम के बजाय तारीख का उपयोग करके घंटों से निपटने की आवश्यकता से बचा जाता है। निम्नलिखित नमूने का उपयोग करें: noTime तारीख की घोषणा करें = getdate (), withTime डेटाटाइम = getdate () @ noTime, @ withTime का चयन करें
ozkary

1
अगर आपको सिर्फ तारीख की जरूरत है तो कास्ट बढ़िया है। हालाँकि अक्सर आपको आधी रात को वर्तमान तिथि की आवश्यकता होती है, इसलिए आप आगे की तारीख में हेरफेर कर सकते हैं। DATEडेटा समय यह आप DATEADD, DateDiff जैसी चीजों के संबंध में और अन्य दिनांक / समय डेटा प्रकार के साथ बातचीत के साथ क्या करने देगा क्या पर अप्रिय प्रतिबंधक है। उन मामलों के लिए, DATEADD()दृष्टिकोण राजा का शासन करता है।
Xedni

यह हर डेट के लिए काम नहीं करता है। मैंने वर्ष के 0218बजाय गलती से प्रवेश किया था 2018और DATEDIFFआपके बयान का एक हिस्सा एक अपवाद की The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range datetime valueकोशिश करता है:select DATEDIFF(dd, 0, convert(datetime2(0), '0218-09-12', 120))
बर्नहार्ड डब्लर

1
@ बर्नहार्डडब्लर ने जुलाई 2009 में जब मैंने उत्तर दिया, "0218" एक वैध तारीख होगी तो आपको यह अब तक नहीं मिला होगा। इसके अलावा "0" डेटाटाइम 2 के लिए 19000101 में परिवर्तित नहीं होता है। इस चयन का प्रयास करेंSELECT DATEDIFF(dd, '19000101', convert(datetime2(0), '0218-09-12', 120))
gbn

69

SQL Server 2008 में, आप उपयोग कर सकते हैं:

CONVERT(DATE, getdate(), 101)

13
तीसरे तर्क का ए से परिवर्तित करने पर परिणाम पर कोई असर नहीं पड़ता datetimeहै date, और इसलिए आपका समाधान प्रभावी रूप से सिर्फ उबलता है CONVERT(DATE,getdate()), जो पहले से ही एक से अधिक बार सुझाया जा चुका है।
एंड्री एम

बस उपयोग CAST(GETDATE() AS DATE)या कड़ाई से ANSI CAST(CURRENT_TIMESTAMP AS DATE)जो मुझे लगता है कि बेकार है। पहले वाले के साथ रहे।
इवानजिनो

52

बेशक यह एक पुराना धागा है लेकिन इसे पूरा करने के लिए।

SQL 2008 से आप DATE डेटाटाइप का उपयोग कर सकते हैं ताकि आप बस कर सकें:

SELECT CONVERT(DATE,GETDATE())

21
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)

... नहीं है नीचे टिप्पणी के अनुसार, एक अच्छा समाधान है।

मैं इस उत्तर को हटा दूंगा, लेकिन मैं इसे एक काउंटर-उदाहरण के रूप में छोड़ दूंगा क्योंकि मुझे लगता है कि टिप्पणीकारों की व्याख्या क्यों यह एक अच्छा विचार नहीं है, अभी भी उपयोगी है।


GBN का जवाब देखें, कई लोगों ने इसकी जांच की है। DATETIMEs को फ़्लोट्स के रूप में संग्रहीत नहीं किया जाता है, और इसलिए DATEADD / DatedIFF का उपयोग करने से गणित के हेरफेर से बचा जाता है जो कि प्रकारों के बीच CAST करने की आवश्यकता है।
MatBailie

मैं स्वीकार कर सकता हूं कि आप जिस कारण का वर्णन करते हैं, उसके लिए DATETIME से FLOAT तक किसी कलाकार से बचना चाहते हैं, लेकिन उस स्थिति में ओपी विकल्प (ए) में शून्य से निहित रूपांतरण भी समस्या नहीं है? हम्म् ... मुझे लगता है कि इस मामले में यह एक FLOAT नहीं है और यह कि सर्वर शायद समय की जानकारी को छोड़ने के लिए पर्याप्त स्मार्ट है। ठीक है, मैं मनाता हूं :-)
गैरी मैकगिल

0 वास्तव में एक DATETIME के ​​संख्यात्मक प्रकार (INT मुझे लगता है) से एक अंतर्निहित रूपांतरण है। क्योंकि यह एक स्थिर अभिव्यक्ति है, हालांकि, आशावादी ऐसा कर सकता है कि संग्रहीत प्रक्रियाओं के लिए संकलन समय पर और SQL को गतिशील रूप से निष्पादित करने के लिए केवल एक बार ऐसा करने की आवश्यकता है। संक्षेप में, उसके लिए एक समय ओवरहेड है, FLOAT आधारित क्वेरी में प्रत्येक पंक्ति के लिए समान ओवरहेड है।
मटैबी जूल 26'09

तैरने के लिए कास्टिंग बहुत अनिश्चित है। यह उत्तर हटा दिया जाना चाहिए। किसी को भी इस कोड का उपयोग नहीं करना चाहिए।
usr

3
यह उल्लेख करने के लिए नहीं कि तैरने के लिए कास्ट और डेटाइम पर वापस जाना सुरक्षित नहीं है - फ्लोट में पर्याप्त सटीकता नहीं है। इसलिए मुझे लगता है कि यह बिल्कुल अनुशंसित नहीं किया जा सकता है। अधिक विस्तार के लिए इस पोस्ट को देखें
ErikE

17

SQL Server 2008 में, DATE डेटाटाइप (एक टाइम डेटाटाइप) भी है।

CAST(GetDate() as DATE)

या

declare @Dt as DATE = GetDate()

यह वही है जो मैंने इस्तेमाल किया और इसने अच्छा काम किया। सबसे सरल उत्तर की तरह लगता है। संयोजन w / CONVERT में उपयोग करने पर कोई डाउनसाइड?
जोएलमदेव

1
CAST और CONVERT फंक्शन में बराबर हैं। अंतर यह है कि CAST ANSI मानक का हिस्सा है, जबकि CONVERT T-SQL के लिए विशिष्ट है। इसलिए, जहाँ भी संभव हो CAST का उपयोग करें।
ट्रॉय

@ ट्रॉय मैं CAST का उपयोग करता हूं क्योंकि मैं 3 टाइपिंग लेटर्स को बचा सकता हूं और वाक्य रचना CONVERT की तुलना में स्पष्ट है, ANSI मानक भाग बेकार है
इवानजिन्हो

8

यहाँ अभी तक एक और उत्तर है, एक और डुप्लिकेट प्रश्न से:

SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime) 

यह मैजिक नंबर विधि DATEADD विधि की तुलना में थोड़ा तेज प्रदर्शन करती है। (यह ~ 10% की तरह दिखता है)

एक लाख रिकॉर्ड के कई दौर पर सीपीयू समय:

DATEADD   MAGIC FLOAT
500       453
453       360
375       375
406       360

लेकिन ध्यान दें कि ये संख्या संभवतः अप्रासंगिक हैं क्योंकि वे पहले से ही बहुत तेज़ हैं। जब तक मेरे पास 100,000 या अधिक के रिकॉर्ड सेट नहीं थे, तब तक मैं शून्य से ऊपर पढ़ने के लिए सीपीयू समय भी नहीं पा सका था।

इस तथ्य को ध्यान में रखते हुए कि DateAdd इस उद्देश्य के लिए है और अधिक मजबूत है, मैं कहूंगा कि DateAdd का उपयोग करें।


1
वह भयानक है। मैंने कभी इस तरह अपना डेटा जोखिम में नहीं डाला। कौन जानता है कि यह सभी डेटासेट के लिए सही है , न कि केवल आपके द्वारा परीक्षण किए गए।
usr

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

@ अच्छा मुद्दा। आपका उत्तर यह उपयोग करने की संभावना प्रदान करता है '12:00:00.003'जो मुझे लगता है कि बहुत बेहतर है, हालांकि।
usr

6
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)

4
एक वैध विकल्प, हाँ। हालांकि इस धागे में एक से अधिक बार सुझाव दिया गया है।
एंड्री एम

ईमानदारी से, यह समाधान पढ़ने में सबसे आसान है। मेरा गोटो
BelgoCanadian

5

मैं वास्तव में पसंद करता हूं:

[date] = CONVERT(VARCHAR(10), GETDATE(), 120)

120प्रारूप कोड आईएसओ 8601 मानक में तारीख विवश होगा:

'YYYY-MM-DD' or '2017-01-09'

सुपर डुप्पर ( R) और पांडा ( Python) में उपयोग करना आसान है !


3

सावधान!

पद्धति a) और b) में हमेशा समान आउटपुट नहीं होता है!

select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)

आउटपुट: 2014-01-01 00:00:00.000

select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)

आउटपुट: 2013-12-31 00:00:00.000

(एमएस SQL ​​सर्वर 2005 और 2008 R2 पर परीक्षण किया गया)

EDIT: एडम की टिप्पणी के अनुसार, यदि आप तालिका से दिनांक मान को पढ़ते हैं, तो ऐसा नहीं हो सकता है, लेकिन ऐसा तब हो सकता है जब आप अपना दिनांक मान एक शाब्दिक (उदाहरण के लिए: ADO.NET के माध्यम से संग्रहीत कार्यविधि के एक पैरामीटर के रूप में) प्रदान करते हैं।


1
.999 को एक DATETIMEकॉलम में SQL सर्वर में संग्रहीत नहीं किया जा सकता है । सबसे अधिक उपलब्ध है .997 From: msdn.microsoft.com/en-us/library/ms187819.aspx आप देखेंगे कि मानों को हजारवें स्थान पर 0, 3 या 7 पर रखा गया है। ओपी नहीं देखेगा अपने टेबलों में अपने परीक्षण से मूल्य।
एडम वेंगर

तुम सही हो। ओपी के सवाल के जवाब के रूप में मुझे यह पोस्ट करने का मतलब नहीं था, लेकिन दूसरों को देखने के लिए एक टिप्पणी के रूप में, लेकिन मेरे पास केवल 11 प्रतिष्ठा अंक थे और टिप्पणी करने के लिए 15 की आवश्यकता है।
ब्रॉस्लेव

आपके पहले स्निपेट में स्ट्रिंग स्थिरांक को कथित रूप से डेटाटाइम में बदल दिया जाता है, आपके दूसरे में यह एक स्ट्रिंग रहता है (और 113 को केवल अनदेखा किया जाता है)।
एंड्री एम

2

पहली बार आवेषण / अपडेट पर पट्टी समय। ऑन-द-फ्लाई रूपांतरण के लिए, कोई भी उपयोगकर्ता-परिभाषित फ़ंक्शन maintanability- वार को हरा नहीं सकता है:

select date_only(dd)

date_onlyआप जैसा चाहें कुछ भी लागू कर सकते हैं - अब यह दूर है और कॉलिंग कोड बहुत अधिक क्लीनर है।


मैंने एक बार चयनित कॉलम से बार स्क्रब करने के लिए ट्रिगर तैयार किया था। यदि डेटा खराब नहीं हो सकता है, तो आपको इसे साफ करने की आवश्यकता नहीं है।
फिलिप केली

2
UDF दृष्टिकोण के लिए एक नकारात्मक पहलू है, वे SARGable नहीं हैं। यदि JOINs या WHERE क्लॉस में उपयोग किया जाता है, तो ऑप्टिमाइज़र प्रदर्शन को बेहतर बनाने के लिए INDEX का उपयोग नहीं कर सकता है। DATEADD / DatedIFF दृष्टिकोण का उपयोग करना, हालांकि, SARGable है और INDEXes से लाभ प्राप्त करने में सक्षम होगा। (जाहिर है FLOAT विधि SARGable भी है)
MatBailie

1
@MatBailie मैं अलग भीख माँगता हूँ! UDF निश्चित रूप से SARGable नहीं हैं, लेकिन न तो Dateadd है और न ही फ्लोट में कन्वर्ट है! WHERE DateAdd(DateDiff(Column)) = @DateValueएक सूचकांक का उपयोग नहीं करेंगे। दूसरी ओर, WHERE Column >= dbo.UDF(@DateValue) AND Column < dbo.UDF(@DateValue + 1) है SARGable। इसलिए सावधान रहें कि आप इसे कैसे लगाते हैं।
एरिक

2

यह प्रश्न देखें:
मैं SQL सर्वर में डेटाइम को कैसे काट सकता हूं?

जो कुछ भी आप करते हैं, स्ट्रिंग विधि का उपयोग न करें । यह सबसे बुरा तरीका है जो आप इसे कर सकते हैं।


धन्यवाद, मुझे लगा कि यह पहले पूछा गया था। अजीब बात यह है कि मेरे प्रयोगों ने बताया कि फ्लोट विधि वास्तव में डेटाडीड (dd, 0, datediff (dd, 0, getDate ()) विधि की तुलना में SQL Server 2008 पर 3.5% कम है। मैंने प्रत्येक विधि के लिए कई बार अपने परीक्षण चलाए और डेटाबेस सर्वर उस समय किसी और चीज के लिए अप्रयुक्त था।
स्टीफन पेरेलसन

आइए हम कहते हैं कि मैं किसी के द्वारा किए गए बेंचमार्क पर संदेह करता हूं, जिन्होंने यह प्रदर्शित नहीं किया है कि वे नियमित रूप से और बहुत ही वैज्ञानिक तरीके से अपनी नौकरी के हिस्से के रूप में बेंचमार्क करते हैं। यहां तक ​​कि gbn द्वारा लिंक में थॉमस के बेंचमार्क को देखने पर कुछ स्पष्ट समस्याएं हैं। यह जरूरी नहीं कि गलत है, बस निश्चित नहीं है। कास्ट / फ्लोर / कास्ट मेथड को बहुत लंबे समय तक सबसे तेजी से स्वीकार किया गया तरीका था, और मुझे संदेह है कि यह एक बार निर्विवाद रूप से सच था। उस ने कहा, मैं इस पर पुनर्विचार करना शुरू कर रहा हूं; विशेष रूप से sql सर्वर 2008 के लिए, जहाँ यह पूरी तरह से अनावश्यक है।
जोएल कोएहॉर्न

1
स्ट्रिंग विधि का उपयोग करना, पढ़ना और याद रखना बेहद आसान है। वे बहुत महत्वपूर्ण कारक हैं जो मुझे लगता है कि आप कम करके आ रहे हैं!
बेन

1
@JoelCoehoorn, कन्वर्ट स्टाइल 121 को "ODBC Canonical" कहा जाता है। यह टकराव या स्थान के साथ भिन्न नहीं होता है। स्ट्रिंग ट्रिक को वर्ष, वर्ष + महीना, दिन, घंटा या मिनट को सामान्य करना भी आसान है।
बेन

1
@Ben स्ट्रिंग ट्रिक डेवलपर्स को स्ट्रिंग रूपांतरण का उपयोग करना सिखाता है। वे काम करते हैं , लेकिन तारीख गणित दूर है, बहुत बेहतर है, कई कारणों से, जिनमें से कम से कम गति नहीं है - लेकिन इससे भी अधिक, क्या तारीखों के साथ काम करने के लिए सीखने के रूप में, डेवलपर और उसकी मानसिक क्षमताओं पर भरोसा करता है कोड में संख्या हेरफेर के साथ तरल होना।
ErikE

2

पहले से ही उत्तर दिया गया है, लेकिन बीमार इसे बाहर भी फेंक देते हैं ... यह बहुत अच्छी तरह से भी बेहतर होता है, लेकिन यह फ्लोट से दशमलव (जो समय संग्रहीत करता है) को फेंककर और केवल पूरे हिस्से को वापस कर देता है (जो कि तारीख है)

 CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)

दूसरी बार मुझे यह समाधान मिला ... मैंने इस कोड को पकड़ लिया


1
तैरने के लिए परिवर्तित करना सुरक्षित नहीं है
ErikE

2
CAST(round(cast(getdate()as real),0,1) AS datetime)

यह विधि स्ट्रिंग फ़ंक्शन का उपयोग नहीं करती है। Dateमूल रूप से दशमलव का एक दिन होने से पहले अंकों के साथ एक वास्तविक डेटा टाइप है।

मुझे लगता है कि यह बहुत तेजी से होगा।


1
फ्लोट के रूप में कास्टिंग सुरक्षित नहीं है
ErikE

2

मेरे लिए नीचे दिया गया कोड हमेशा विजेता होता है:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));


1
फ्लोट के रूप में कास्टिंग सुरक्षित नहीं है
ErikE

2

CONVERT (चार (10), गेटडेट) (126) का चयन करें


आपके सुझाव का मुख्य अंतर @ broslav के उत्तर में वर्णित विधि से या इस थ्रेड में सबसे धीमी गति से निर्धारित विधि के अनुसार (स्वीकृत उत्तर में उसी लिंक) से है?
एंड्री एम

1

मुझे लगता है तुम्हारा मतलब cast(floor(cast(getdate()as float))as datetime)

असली केवल 32-बिट है, और कुछ जानकारी खो सकता है

यह सबसे तेज है cast(cast(getdate()+x-0.5 as int)as datetime)

... हालांकि केवल 10% तेजी से(about 0.49 microseconds CPU vs. 0.58)

यह अनुशंसा की गई थी, और अभी मेरे परीक्षण में एक ही समय लगता है: DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

SQL 2008 में, SQL CLR फ़ंक्शन, SQL फ़ंक्शन का उपयोग करने की तुलना में लगभग 5 गुना अधिक तेज़ होता है। 1.35 microseconds बनाम 6.5 microsections में, SQL CLR फ़ंक्शन बनाम एक साधारण SQL UDF के लिए बहुत कम फ़ंक्शन-कॉल ओवरहेड का संकेत देता है।

SQL 2005 में, SQL CLR फ़ंक्शन मेरी धीमी गति से, मेरे परीक्षण के अनुसार, 16 गुना तेज़ है:

create function dateonly (  @dt datetime )
returns datetime
as
begin
return cast(floor(cast(@dt as float))as int)
end

1

कैसे के बारे में select cast(cast my_datetime_field as date) as datetime)? यह उसी तिथि को परिणाम देता है, जिसमें समय 00:00 बजे सेट होता है, लेकिन पाठ में किसी भी रूपांतरण से बचा जाता है और किसी भी स्पष्ट संख्यात्मक गोलाई से बचा जाता है।



वे एक जैसे नहीं हैं। अन्य उत्तरों ने सुझाव दिया कि इसे बिना किसी समय के घटक के साथ डेट पर ले जाएं और इसे ऐसे ही छोड़ दें। मेरी पोस्टिंग इसे आधी रात के समय के साथ एक डेटटाइम पर सेट करती है। एक बड़ा अंतर है; MS Excel में एक्सपोर्ट करने की कोशिश करें और आप देखेंगे कि यह डेटाइम को डेट से बेहतर तरीके से हैंडल करता है।
डॉ। ड्रू

पहला वाला बिल्कुल एक जैसा है।
मिकेल एरिकसन

ठीक है, हाँ, मैं अब वही देख रहा हूँ। यदि आवश्यक हो, तो मुझे अपने उत्तर को एक डुप्लिकेट के रूप में निकालने में खुशी होगी।
डॉ। ड्रू

1

मुझे लगता है कि यदि आप इसके साथ सख्ती करते हैं TSQLतो यह समय को कम करने का सबसे तेज़ तरीका है:

 select convert(datetime,convert(int,convert(float,[Modified])))

मैंने इस ट्रंकेशन विधि को विधि की तुलना में लगभग 5% तेज पाया DateAdd। और इसे इस तरह निकटतम दिन के लिए आसानी से संशोधित किया जा सकता है:

select convert(datetime,ROUND(convert(float,[Modified]),0))

तैरने के लिए परिवर्तित करना सुरक्षित नहीं है
ErikE

1

यहां मैंने SQL सर्वर के लिए डेटाइम के कुछ हिस्सों को हटाने के लिए एक फ़ंक्शन बनाया। उपयोग:

  • पहले परम को छीन लिया जाने वाला डेटाइम है।
  • दूसरा परम एक चर है:
    • s: सेकंड के लिए दौर; मिलीसेकंड निकालता है
    • मी: राउंड टू मिनट; सेकंड और मिलीसेकंड निकालता है
    • एच: घंटों तक गोल; मिनट, सेकंड और मिलीसेकंड निकालता है।
    • डी: दिनों के लिए दौर; घंटे, मिनट, सेकंड और मिलीसेकंड निकालता है।
  • नया डेटाटाइम लौटाता है

create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end


धन्यवाद एंड्री! मुझे नहीं पता था कि मेरी सिफारिश कुशल नहीं थी। कम से कम यह काम करता है, लेकिन आप सही हैं।
मैक्स वर्गास

1

बस किसी के मामले में Sybase संस्करण के लिए यहाँ देख रहा है क्योंकि ऊपर के कई संस्करण काम नहीं कर रहे हैं

CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
  • Adaptive Server 15.7 पर चलने वाले I SQL v11 में परीक्षण किया गया

यह स्वीकार किए गए उत्तर पर एक संपादन के रूप में बेहतर है। 20 अन्य जवाबों के साथ यह दफन हो जाएगा और निकाह अधूरा होगा। स्वीकृत उत्तर भी उपयोग करने का उल्लेख करता है cast: SQL Server 2008+ के लिए, आप तिथि कर सकते हैं। या सिर्फ तारीख का उपयोग करें ताकि हटाने का समय न हो।
EWit

यह बराबर Sybase प्रश्न के उत्तर के रूप में पोस्ट करना सबसे अच्छा होगा। यदि ऐसा कोई प्रश्न नहीं है, तो आप एक बनाने के लिए स्वतंत्र हैं (और इसका उत्तर स्वयं दें)।
एंड्री एम

इसके अलावा, जब आप एक datetimeको परिवर्तित कर रहे हैं, तो CONVERT को तीसरा पैरामीटर निर्दिष्ट करना व्यर्थ है date: दोनों में से कोई भी एक अंतर्निहित प्रारूप नहीं है।
एंड्री एम।

0

यदि संभव हो, तो इस तरह की विशेष चीजों के लिए, मैं सीएलआर कार्यों का उपयोग करना पसंद करता हूं।

इस मामले में:

[Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime DateOnly(SqlDateTime input)
    {
        if (!input.IsNull)
        {
            SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);

            return dt;
        }
        else
            return SqlDateTime.Null;
    }

0

यदि मैं SQL सर्वर 2005 (या लोअर वर्जन) के साथ काम कर रहा हूं, तो मैं व्यक्तिगत रूप से लगभग हमेशा इसके लिए उपयोगकर्ता परिभाषित कार्यों का उपयोग करता हूं, हालांकि, यह ध्यान दिया जाना चाहिए कि यूडीएफ का उपयोग करने के लिए विशिष्ट कमियां हैं, खासकर यदि उन्हें WHERE क्लॉज पर लागू किया जाता है (नीचे देखें और) आगे के विवरण के लिए इस उत्तर पर टिप्पणियाँ)। यदि SQL Server 2008 (या उच्चतर) का उपयोग कर रहे हैं - नीचे देखें।

वास्तव में, मेरे द्वारा बनाए जाने वाले अधिकांश डेटाबेस के लिए, मैं इन यूडीएफ को शुरू में ही पास में जोड़ देता हूं क्योंकि मुझे पता है कि 99% संभावना है कि मैं जल्दी या बाद में उनकी आवश्यकता होने जा रहा हूं।

मैं "केवल दिनांक" और "केवल समय" के लिए एक बनाता हूं (हालाँकि "तिथि केवल" एक ही है जो दोनों का सबसे अधिक उपयोग किया जाता है)।

यहां विभिन्न प्रकार के दिनांक से संबंधित UDF के कुछ लिंक दिए गए हैं:

एसेंशियल एसक्यूएल सर्वर डेट, टाइम और डेटटाइम फंक्शंस में
डेट को केवल फंक्शन मिलता है

यह अंतिम लिंक किसी डेटटाइम फ़ील्ड के केवल भाग को प्राप्त करने के 3 अलग-अलग तरीकों से कम नहीं दिखाता है और प्रत्येक दृष्टिकोण के कुछ पेशेवरों और विपक्षों का उल्लेख करता है।

यदि UDF का उपयोग किया जाता है, तो यह ध्यान दिया जाना चाहिए कि आपको क्वेरी में WHERE क्लॉज़ के भाग के रूप में UDF के उपयोग से बचने का प्रयास करना चाहिए क्योंकि इससे क्वेरी के प्रदर्शन में बहुत बाधा होगी। इसका मुख्य कारण यह है कि WHD क्लॉज में UDF का उपयोग करने से गैर-सारगर्भित क्लॉज का प्रतिपादन होता है , जिसका अर्थ है कि SQL सर्वर अब क्वेरी के निष्पादन की गति को बेहतर बनाने के लिए उस क्लॉज के साथ एक इंडेक्स का उपयोग नहीं कर सकता है। UDF के अपने स्वयं के उपयोग के संदर्भ में, मैं अक्सर "कच्चे" तिथि कॉलम का उपयोग WHERE क्लॉज के भीतर करूंगा, लेकिन UDF को चयनित कॉलम में लागू करूंगा। इस तरह, UDF केवल फ़िल्टर किए गए परिणाम-सेट पर लागू होता है और फ़िल्टर के भाग के रूप में तालिका की प्रत्येक पंक्ति नहीं होती है।

बेशक, इसके लिए पूर्ण सर्वोत्तम दृष्टिकोण SQL Server 2008 (या उच्चतर) का उपयोग करना है और अपनी तिथियों और समय को अलग करना है , क्योंकि SQL सर्वर डेटाबेस इंजन मूल रूप से व्यक्तिगत तिथि और समय घटकों को प्रदान कर रहा है, और कुशलतापूर्वक इनकी क्वेरी कर सकता है समग्र डेटाइम प्रकार से दिनांक या समय भाग निकालने के लिए एक UDF या अन्य तंत्र की आवश्यकता के बिना।


यूडीएफ का उपयोग करना कुछ स्थितियों में अच्छा हो सकता है (जैसे कि मानकों को खंगालना)। लेकिन ज्यादातर स्थितियों में यह एक भयानक समाधान है - प्रत्येक पंक्ति के लिए एक बार यूडीएफ चलाना एक क्वेरी के प्रदर्शन को मारने का एक तरीका है , इसके लिए कोई आवश्यकता नहीं है!
ErikE

@ एरिक - मैं असहमत नहीं हूं, एरिक, यूडीएफ के प्रदर्शन हत्यारे हैं, यही कारण है कि मैं कहता हूं कि, यदि आप SQL सर्वर 2008 या इसके बाद के संस्करण का उपयोग कर सकते हैं और एक अंतर्निहित डेटाटाइप का उपयोग कर सकते हैं जो आपके लिए ऐसा करता है, तो यह सबसे अच्छा समाधान होगा (आवश्यकता के अनुरूप और प्रदर्शन के मामले में दोनों ही)। यदि आप SQL सर्वर के पुराने संस्करण के साथ फंस गए हैं जो मूल रूप से इसका समर्थन नहीं करता है, तो आप हार मानने वाले हैं अपनी आवश्यकताओं को प्राप्त करने के लिए कुछ हैं।
क्रेगटीपी

सच। यह अच्छा होगा यदि डेटाबेस इंजन ने हमें कुछ दिया जो SARGable था, लेकिन व्यक्त करना आसान था। इस बीच, यदि आप पूरे दिन के दौरान किसी भी समय एक मूल्य की तलाश कर रहे हैं, तो यह अभी भी सबसे अच्छा समाधान है (कम से कम पुराने संस्करणों के लिए SQL):WHERE DateColumn >= {TimeTruncatingExpression}(@DateValue) AND DateColumn < {TimeTruncatingExpression}(@DateValue + 1) :। मुझे ऐसा महसूस हुआ कि मुझे कुछ कहना था क्योंकि आपने कहा था "मैं लगभग हमेशा यूडीएफ का उपयोग करता हूं" किसी भी तरह की कमियां नहीं बताई गई, न ही एक तारीख-केवल क्वेरी SARGable बनाने का तरीका।
ErikE

@ एरिक - कोई चिंता नहीं, एरिक। जब मैंने यूडीएफ का उपयोग किया है, तो मैं या तो छोटे डेटा सेट के साथ काम कर रहा हूं जहां प्रदर्शन सर्वोपरि नहीं है, या अधिक संभावना है कि मैं "कच्ची" तिथि फ़ील्ड (बर्खास्तगी सुनिश्चित करने के लिए) के खिलाफ क्वेरी को फ़िल्टर कर रहा हूं लेकिन कॉलम का चयन करना यूडीएफ के साथ आवेदन किया। जैसा कि ये आमतौर पर छोटे डेटासेट होते हैं, एक बार फ़िल्टर किए जाते हैं, इस छोटी संख्या के रिकॉर्ड पर UDF चल रहा है, ऐसा प्रदर्शन हिट नहीं है। उस ने कहा, आप एक बहुत अच्छा मुद्दा उठाते हैं और मैंने इसे दर्शाने के लिए अपना जवाब अपडेट कर दिया है।
क्रेगटीपी

-4

मै इस्तेमाल करूंगा:

CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
) 

इस प्रकार प्रभावी रूप से आपके पास पहले से मौजूद दिनांक फ़ील्ड से एक नया फ़ील्ड बना रहा है।


2
तुम ऐसा क्यों करोगे? क्या आपको लगता है कि एक datetimeमूल्य से बिट्स को निकालना , उन्हें स्ट्रिंग्स में परिवर्तित करना, उन्हें एक साथ जोड़ना और अंत में परिणाम को वापस datetimeबदलना जैसे मूल datetime( DATEADD/ DATEDIFFविधि) पर प्रत्यक्ष गणना करने से बेहतर है ?
एंड्री एम

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