टी-एसक्यूएल के साथ दिन महीने और वर्ष से तारीख बनाएं


264

मैं SQL सर्वर 2005 में अलग-अलग हिस्सों जैसे कि 12, 1, 2007 को डेटाइम में बदलने की कोशिश कर रहा हूं। मैंने निम्नलिखित प्रयास किए हैं:

CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)

लेकिन इससे गलत तारीख निकलती है। तीन डेट वैल्यू को उचित डेटाइम फॉर्मेट में बदलने का सही तरीका क्या है।


8
कृपया अपने स्वीकृत उत्तर वेबलॉग्स को
ब्रायन वेबस्टर

DATEFROMPARTS (वर्ष, माह, दिन)
केट

जवाबों:


174

y, m, dसभी मानते हैं int, कैसे के बारे में:

CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)

कृपया SQL सर्वर 2012 और इसके बाद के संस्करण के लिए मेरा अन्य उत्तर देखें


बुरा। मुझे 1 जनवरी 0001
ओलेग डॉक

24
ओलेग एसक्यूएल सर्वर डेटाइम आगे पीछे नहीं जाते हैं फिर 1753-01-01 कुछ।
कोडमोंकी जूल

2
यदि आप निर्दिष्ट नहीं करते हैं, तो यह उत्तर तारीख प्रारूप सेटिंग्स पर निर्भर करता है, जो आपके सर्वर की क्षेत्रीय सेटिंग्स पर निर्भर हैं। yyyymmddप्रारूप उन सेटिंग्स की परवाह किए बिना काम करता है। "एक छह या आठ अंकों की स्ट्रिंग हमेशा ymd के रूप में व्याख्या की जाती है ।" docs.microsoft.com/en-us/sql/t-sql/data-types/… इस उत्तर को देखें: stackoverflow.com/a/46064419/2266979
रिले मेजर

339

इसे इस्तेमाल करे:

Declare @DayOfMonth TinyInt Set @DayOfMonth = 13
Declare @Month TinyInt Set @Month = 6
Declare @Year Integer Set @Year = 2006
-- ------------------------------------
Select DateAdd(day, @DayOfMonth - 1, 
          DateAdd(month, @Month - 1, 
              DateAdd(Year, @Year-1900, 0)))

यह अच्छी तरह से काम करता है, किसी भी स्ट्रिंग रूपांतरणों को न करने का लाभ जोड़ा है, इसलिए यह शुद्ध अंकगणित प्रसंस्करण (बहुत तेज) है और यह किसी भी तारीख के प्रारूप पर निर्भर नहीं है। यह इस तथ्य पर कैपिटल करता है कि एसक्यूएल सर्वर का आंतरिक प्रतिनिधित्व डेटाइम और स्मालडेनटाइम वैल्यूज़ के लिए एक दो है भाग का पहला भाग जिसका एक पूर्णांक 1 जनवरी 1900 से दिनों की संख्या का प्रतिनिधित्व करता है, और दूसरा भाग एक दशमलव अंश है जो एक दिन के आंशिक भाग का प्रतिनिधित्व करता है (समय के लिए) --- इसलिए पूर्णांक मान 0 (शून्य) ) हमेशा 1 जनवरी 1900 की आधी रात में सीधे अनुवाद करता है ...

या, धन्यवाद से सुझाव देने के लिए @brinary,

Select DateAdd(yy, @Year-1900,  
       DateAdd(m,  @Month - 1, @DayOfMonth - 1)) 

अक्टूबर 2014 को संपादित किया गया। जैसा कि @cade Roux द्वारा देखा गया है, SQL 2012 में अब एक बिल्ट-इन फ़ंक्शन है:
DATEFROMPARTS(year, month, day)
वही काम करता है।

3 अक्टूबर 2016 को संपादित, (इसे नोट करने के लिए @bambams के लिए धन्यवाद, और इसे ठीक करने के लिए @brinary), अंतिम समाधान, @brinary द्वारा प्रस्तावित। जब तक वर्षों के अलावा पहले प्रदर्शन नहीं किया जाता है तब तक लीप वर्षों के लिए काम नहीं करता है

select dateadd(month, @Month - 1, 
     dateadd(year, @Year-1900, @DayOfMonth - 1)); 

36
@ वृंद, आपको इस उत्तर के रूप में चिह्नित करना चाहिए। यह सबसे अच्छा है। इसे अन्य StackOverflow पाठकों की सेवा के रूप में करें।
बिल पैत्ज़के

3
लीप वर्ष के लिए काम करता है: चुनें डेटीड (मिमी, (@ y-1900) * 12 + @ @ - 1,0) + (@ डी -1)
छिपा हुआ

8
जब मान्य मानों का अवैध संयोजन पारित किया गया है @Year = 2001, @Month = 13और @DayOfMonth = 32परिणाम में मान्य मान्य तारीख परिणाम में परिणाम है 2002-02-01T00:00:00.000। स्वीकृत उत्तर (कैड रूक्स द्वारा) एक त्रुटि उत्पन्न करता है, जो अधिक उपयोगी है।
onedaywhen

6
आपको शून्य से शुरू करने और दिनों को जोड़ने की आवश्यकता नहीं है। आप सीधे @ DayOfMonth-1 से शुरू कर सकते हैं, फिर महीनों और वर्षों को जोड़ सकते हैं। यह एक कम DateAdd () है!
२३:११ की

2
मेरे सिर की अभी भी कताई है - वहाँ वास्तव में ऐसा करने के लिए एक रास्ता नहीं है? (मुझे SQL Server 2005 में एक क्वेरी को ठीक करने का काम सौंपा गया है)
पीटर पेर्हैव

241

SQL सर्वर 2012 में एक अद्भुत और लंबे समय से प्रतीक्षित नया DATEFROMPARTS फ़ंक्शन है (जो कि यदि दिनांक अमान्य है - तो इस समस्या के लिए DATEADD- आधारित समाधान पर मेरी मुख्य आपत्ति है):

http://msdn.microsoft.com/en-us/library/hh213228.aspx

DATEFROMPARTS(ycolumn, mcolumn, dcolumn)

या

DATEFROMPARTS(@y, @m, @d)

11
इसके अलावा, मूल प्रश्न का उल्लेख करते हुए, जहाँ डेटाटाइम ऑब्जेक्ट का उल्लेख किया गया था, DATETIMEFROMPARTS: msdn.microsoft.com/pl-pl/library/hh213233%28v=sqb.110%29.aspx
Maciej Jaśniaczyk

116

या केवल एक एकल काम का उपयोग कर कार्य:

DECLARE @day int, @month int, @year int
SELECT @day = 4, @month = 3, @year = 2011

SELECT dateadd(mm, (@year - 1900) * 12 + @month - 1 , @day - 1)

4
सबसे अच्छा जवाब IMO। चार्ल्स के जवाब के सभी फायदे हैं, और बहुत कम है।
माइकल

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

16

Sql Server 2012 में एक फ़ंक्शन है जो भागों ( DATEFROMPARTS ) के आधार पर दिनांक बनाएगा । हम में से बाकी के लिए, यहाँ एक db फ़ंक्शन है जो मैंने बनाया है जो भागों से तारीख निर्धारित करेगा (धन्यवाद @Charles) ...

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[func_DateFromParts]'))
    DROP FUNCTION [dbo].[func_DateFromParts]
GO

CREATE FUNCTION [dbo].[func_DateFromParts]
(
    @Year INT,
    @Month INT,
    @DayOfMonth INT,
    @Hour INT = 0,  -- based on 24 hour clock (add 12 for PM :)
    @Min INT = 0,
    @Sec INT = 0
)
RETURNS DATETIME
AS
BEGIN

    RETURN DATEADD(second, @Sec, 
            DATEADD(minute, @Min, 
            DATEADD(hour, @Hour,
            DATEADD(day, @DayOfMonth - 1, 
            DATEADD(month, @Month - 1, 
            DATEADD(Year, @Year-1900, 0))))))

END

GO

आप इसे इस तरह कह सकते हैं ...

SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT)

रिटर्न ...

2013-10-04 15:50:00.000

12

CAST के बजाय CONVERT आज़माएं।

CONVERT एक तीसरे पैरामीटर को दिनांक प्रारूप का संकेत देता है।

प्रारूपों की सूची यहां है: http://msdn.microsoft.com/en-us/library/ms187928.aspx

एक अन्य उत्तर के बाद "सही" उत्तर के रूप में अद्यतन किया गया है:

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


सहमत होने के लिए प्रारूप को योग्य होने की आवश्यकता है, जैसे CONVERT (datetime2, CAST (@year AS varchar) + '।' + CAST (@month AS varchar) + '।' + CAST (@day AS varchar), 102)
टोनी वॉल।

9

आप भी उपयोग कर सकते हैं

select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3 
From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd

SQL में कार्य करता है ver.2012 और AzureSQL के बाद से


6

यह एक स्पष्ट प्रारंभिक बिंदु '19000101' का उपयोग करने के लिए अधिक सुरक्षित है

create function dbo.fnDateTime2FromParts(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int, @Nanosecond int)
returns datetime2
as
begin
    -- Note! SQL Server 2012 includes datetime2fromparts() function
    declare @output datetime2 = '19000101'
    set @output = dateadd(year      , @Year - 1900  , @output)
    set @output = dateadd(month     , @Month - 1    , @output)
    set @output = dateadd(day       , @Day - 1      , @output)
    set @output = dateadd(hour      , @Hour         , @output)
    set @output = dateadd(minute    , @Minute       , @output)
    set @output = dateadd(second    , @Second       , @output)
    set @output = dateadd(ns        , @Nanosecond   , @output)
    return @output
end

सिर्फ declare @output datetime2 = 0और सिर्फ इस्तेमाल की जगह इस्तेमाल क्यों नहीं @Year - 1900करते @Year - DATEPART(year,0);? यह SQL Server 2008 में किसी भी जाति के बिना काम करता है और बहुत अधिक स्पष्ट है।
tsionyx

क्योंकि वह काम नहीं करेगा। आप 0 से डेटाइम 2 तक नहीं डाल सकते हैं। आपका कोड वापस आ जाएगा "ऑपरेंड प्रकार क्लैश: इंट डेटाइम 2 के साथ असंगत है"
जैक

4

यदि आप इसे बाहर रखना नहीं चाहते हैं, तो यह भी काम करता है (इसे एक समारोह में रखें):

DECLARE @Day int, @Month int, @Year int
SELECT @Day = 1, @Month = 2, @Year = 2008

SELECT DateAdd(dd, @Day-1, DateAdd(mm, @Month -1, DateAdd(yy, @Year - 2000, '20000101')))

4

अगर आपको डेट और टाइम दोनों हिस्सों से डेटटाइम की जरूरत है, तो मैं एक-लाइन समाधान जोड़ता हूं :

select dateadd(month, (@Year -1900)*12 + @Month -1, @DayOfMonth -1) + dateadd(ss, @Hour*3600 + @Minute*60 + @Second, 0) + dateadd(ms, @Millisecond, 0)


2

12 से नीचे के SQL सर्वर संस्करणों के लिए मैं CASTसंयोजन के उपयोग की सिफारिश कर सकता हूंSET DATEFORMAT

-- 26 February 2015
SET DATEFORMAT dmy
SELECT CAST('26-2-2015' AS DATE)

SET DATEFORMAT ymd
SELECT CAST('2015-2-26' AS DATE)

आप उन स्ट्रिंग्स को कैसे बनाते हैं, यह आपके ऊपर है


1

इस प्रश्न को आज़माएं:

    SELECT SUBSTRING(CONVERT(VARCHAR,JOINGDATE,103),7,4)AS
    YEAR,SUBSTRING(CONVERT(VARCHAR,JOINGDATE,100),1,2)AS
MONTH,SUBSTRING(CONVERT(VARCHAR,JOINGDATE,100),4,3)AS DATE FROM EMPLOYEE1

परिणाम:

2014    Ja    1
2015    Ja    1
2014    Ja    1
2015    Ja    1
2012    Ja    1
2010    Ja    1
2015    Ja    1

1

मुझे पता है कि ओपी एसक्यूएल 2005 के जवाब के लिए पूछ रहा है, लेकिन सवाल बहुत पुराना है, इसलिए यदि आप एसक्यूएल 2012 या इसके ऊपर चल रहे हैं तो आप निम्नलिखित का उपयोग कर सकते हैं:

SELECT DATEADD(DAY, 1, EOMONTH(@somedate, -1))

संदर्भ: https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-2017&viewFallbackFrom-sql-server-prepretversions


0

मैं व्यक्तिगत रूप से पदार्थ को प्राथमिकता देता हूं क्योंकि यह आवश्यकतानुसार सफाई और विकल्प को विभाजित करने की क्षमता प्रदान करता है। धारणा यह है कि डेटा 'dd, mm, yyyy' प्रारूप का है।

--2012 and above
SELECT CONCAT (
        RIGHT(REPLACE(@date, ' ', ''), 4)
        ,'-'
        ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(@date, ' ', ''), CHARINDEX(',', REPLACE(@date, ' ', '')) + 1, LEN(REPLACE(@date, ' ', '')) - CHARINDEX(',', REPLACE(@date, ' ', '')) - 5)),2)
        ,'-'
        ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(@date, ' ', ''), 1, CHARINDEX(',', REPLACE(@date, ' ', '')) - 1)),2)
        )

--2008 and below
SELECT   RIGHT(REPLACE(@date, ' ', ''), 4)
        +'-'
        +RIGHT('00'+SUBSTRING(REPLACE(@date, ' ', ''), CHARINDEX(',', REPLACE(@date, ' ', '')) + 1, LEN(REPLACE(@date, ' ', '')) - CHARINDEX(',', REPLACE(@date, ' ', '')) - 5),2)
        +'-'
        +RIGHT('00'+SUBSTRING(REPLACE(@date, ' ', ''), 1, CHARINDEX(',', REPLACE(@date, ' ', '')) - 1),2)

यहां यह दर्शाया गया है कि यदि डेटा को किसी कॉलम में संग्रहीत किया जाता है तो उस पर मुकदमा कैसे किया जा सकता है। यह कहने की आवश्यकता नहीं है कि कॉलम पर आवेदन करने से पहले परिणाम-सेट की जांच करने के लिए इसका आदर्श है

DECLARE @Table TABLE (ID INT IDENTITY(1000,1), DateString VARCHAR(50), DateColumn DATE)

INSERT INTO @Table
SELECT'12, 1, 2007',NULL
UNION
SELECT'15,3, 2007',NULL
UNION
SELECT'18, 11 , 2007',NULL
UNION
SELECT'22 , 11, 2007',NULL
UNION
SELECT'30, 12, 2007  ',NULL

UPDATE @Table
SET DateColumn = CONCAT (
        RIGHT(REPLACE(DateString, ' ', ''), 4)
        ,'-'
        ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateString, ' ', ''), CHARINDEX(',', REPLACE(DateString, ' ', '')) + 1, LEN(REPLACE(DateString, ' ', '')) - CHARINDEX(',', REPLACE(DateString, ' ', '')) - 5)),2)
        ,'-'
        ,RIGHT(CONCAT('00',SUBSTRING(REPLACE(DateString, ' ', ''), 1, CHARINDEX(',', REPLACE(DateString, ' ', '')) - 1)),2)
        ) 

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