दिलचस्प पोस्ट
Wp_nav_menu आइटम में फ़ीचर छवि जोड़ें जावास्क्रिप्ट: पारित वैरिएबल का तर्क मान और नाम प्राप्त करें यदि सेल में '@' सम्मिलित नहीं है, तो पूरे पंक्ति को हटाने का कुशल तरीका क्या कचरा कलेक्टर को आईडीिसपोज़ाबल होगा.मेरे लिए फर्क? रूबी के attr_accessor, attr_reader और attr_writer का उपयोग क्यों करें? पूर्ण एंड्रॉइड अनुप्रयोग के लिए कस्टम फ़ॉन्ट जोड़ें सी + + विज़ुअल स्टूडियो वर्ण एन्कोडिंग समस्याएं प्रोग्रामिंग की जांच करना कि क्या कोई ऐप iPhone पर इंस्टॉल है डेल्फी आवेदन के लिए प्लगइन्स सिस्टम – बीपीएल बनाम डीएलएल? मेरे एंड्रॉइड ऐप में पाठ को कैसे प्रतिलिपि करें? एंड्रॉइड कैमरा से सर्वर पर वीडियो स्ट्रीमिंग स्क्रिप्ट मैनेजर को किसी भी नियंत्रण की आवश्यकता होती है जो इसकी आवश्यकता होती है क्या सी # में एक्सटेंशन विधि के साथ एक कक्षा विधि को ओवरराइड करने के लिए कोई रास्ता है? CSV प्रारूप में Mysqldump XMPP stanza / packet के <message> तत्वों में कस्टम फ़ील्ड कैसे जोड़ें?

फ़ंक्शन का प्रयोग करके दो तिथियों के बीच की तारीखों की एक सूची प्राप्त करें

मेरा प्रश्न इस MySQL प्रश्न के समान है, लेकिन SQL सर्वर के लिए करना है:

क्या कोई फ़ंक्शन या एक क्वेरी है जो दो तिथियों के बीच दिनों की सूची वापस करेगा? उदाहरण के लिए, हम कहते हैं कि विस्फोटडेट्स नामक एक समारोह है:

SELECT ExplodeDates('2010-01-01', '2010-01-13'); 

यह मूल्य के साथ एक एकल स्तंभ तालिका वापस करेगा:

 2010-01-01 2010-01-02 2010-01-03 2010-01-04 2010-01-05 2010-01-06 2010-01-07 2010-01-08 2010-01-09 2010-01-10 2010-01-11 2010-01-12 2010-01-13 

मैं सोच रहा हूँ कि एक कैलेंडर / संख्या तालिका शायद मेरी मदद कर सकती है।


अद्यतन करें

मैंने दिए गए तीन कोड उत्तरों पर एक नज़र डालने का फैसला किया है, और निष्पादन के परिणाम – कुल बैच का% के रूप में – हैं:

  • रोब फ़ार्ले का जवाब : 18%
  • स्टिंगज जेक का जवाब : 41%
  • केएम का जवाब : 41%

नीचा बेहतर है

मैंने रोब फ़ार्ले के जवाब को स्वीकार कर लिया है, क्योंकि यह सबसे तेज़ था, भले ही नंबर की मेज समाधान (उनके उत्तर में केएम और स्टिंगज जेक द्वारा उपयोग किया गया) मेरे पसंदीदा में से कुछ हैं रोब फ़ार्ले का दो-तिहाई तेजी से था

अपडेट 2

अलीविया का उत्तर अधिक संक्षिप्त है। मैंने स्वीकार किए गए उत्तर को बदल दिया है।

Solutions Collecting From Web of "फ़ंक्शन का प्रयोग करके दो तिथियों के बीच की तारीखों की एक सूची प्राप्त करें"

इस तरह से कुछ प्रयास करें:

 CREATE FUNCTION dbo.ExplodeDates(@startdate datetime, @enddate datetime) returns table as return ( with N0 as (SELECT 1 as n UNION ALL SELECT 1) ,N1 as (SELECT 1 as n FROM N0 t1, N0 t2) ,N2 as (SELECT 1 as n FROM N1 t1, N1 t2) ,N3 as (SELECT 1 as n FROM N2 t1, N2 t2) ,N4 as (SELECT 1 as n FROM N3 t1, N3 t2) ,N5 as (SELECT 1 as n FROM N4 t1, N4 t2) ,N6 as (SELECT 1 as n FROM N5 t1, N5 t2) ,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N6) SELECT DATEADD(day,num-1,@startdate) as thedate FROM nums WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1 ); 

फिर आप इसका उपयोग करते हैं:

 SELECT * FROM dbo.ExplodeDates('20090401','20090531') as d; 

संपादित (स्वीकृति के बाद):

कृपया ध्यान दें … यदि आपके पास पहले से ही पर्याप्त बड़ी संख्या में टेबल है तो आपको इसका उपयोग करना चाहिए:

 CREATE FUNCTION dbo.ExplodeDates(@startdate datetime, @enddate datetime) returns table as return ( SELECT DATEADD(day,num-1,@startdate) as thedate FROM nums WHERE num <= DATEDIFF(day,@startdate,@enddate) + 1 ); 

और आप इस तरह का एक टेबल बना सकते हैं:

 CREATE TABLE dbo.nums (num int PRIMARY KEY); INSERT dbo.nums values (1); GO INSERT dbo.nums SELECT num + (SELECT COUNT(*) FROM nums) FROM nums GO 20 

ये पंक्तियाँ 1 एम पंक्तियों वाली संख्याओं की एक तालिका बनायेगी … और उन्हें एक-एक करके डालने की तुलना में तेज

आपको अपने विस्फोटडेट्स फ़ंक्शन का उपयोग करके फ़ंक्शन का निर्माण नहीं करना चाहिए जिसमें BEGIN और END शामिल होता है, क्योंकि क्वेरी ऑप्टिमाइज़र क्वेरी को सरल बनाने में असमर्थ हो जाता है

यह कुछ पंक्तियां एसक्यूएल सर्वर में इस सवाल का सरल उत्तर है।

 WITH mycte AS ( SELECT CAST('2011-01-01' AS DATETIME) DateValue UNION ALL SELECT DateValue + 1 FROM mycte WHERE DateValue + 1 < '2021-12-31' ) SELECT DateValue FROM mycte OPTION (MAXRECURSION 0) 

यह वही है जो आप चाहते हैं, विल की पिछली पोस्ट से संशोधित किया गया। सहायक तालिकाओं या छोरों की कोई आवश्यकता नहीं

 WITH date_range (calc_date) AS ( SELECT DATEADD(DAY, DATEDIFF(DAY, 0, '2010-01-13') - DATEDIFF(DAY, '2010-01-01', '2010-01-13'), 0) UNION ALL SELECT DATEADD(DAY, 1, calc_date) FROM date_range WHERE DATEADD(DAY, 1, calc_date) <= '2010-01-13') SELECT calc_date FROM date_range; 

मैं एक oracle आदमी हूँ, लेकिन मेरा मानना ​​है कि एमएस एसक्यूएल सर्वर क्लॉज द्वारा कनेक्ट करने के लिए समर्थन है:

 select sysdate + level from dual connect by level <= 10 ; 

आउटपुट है:

 SYSDATE+LEVEL 05-SEP-09 06-SEP-09 07-SEP-09 08-SEP-09 09-SEP-09 10-SEP-09 11-SEP-09 12-SEP-09 13-SEP-09 14-SEP-09 

दोहरी सिर्फ एक 'डमी' तालिका है जो ऑरेकल के साथ आती है (इसमें 1 पंक्ति और शब्द 'डमी' एक स्तंभ के मान के रूप में है)।

 DECLARE @MinDate DATETIME = '2012-09-23 00:02:00.000', @MaxDate DATETIME = '2012-09-25 00:00:00.000'; SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) Dates = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate) FROM sys.all_objects a CROSS JOIN sys.all_objects b; 

कुछ विचार:

यदि आपको उनके द्वारा लूप के लिए सूची तिथियों की ज़रूरत होती है, तो आपके पास एक प्रारंभ दिनांक और दिन गणना मानदंड हो सकते हैं और तिथि बनाने और इसका उपयोग करते समय थोड़ी देर लूप करते हैं?

सी # सीएलआर संग्रहित प्रक्रियाओं का उपयोग करें और कोड को सी # में लिखें

इसे कोड में डेटाबेस से बाहर करें

क्या ये तिथियां पहले से ही डेटाबेस में होंगी या क्या आप बस दो तिथियों के बीच के दिन जानना चाहते हैं? यदि यह पहली बार है तो आप बीच के बीच की तारीखों को खोजने के लिए BETWEEN या <=> = का उपयोग कर सकते हैं

उदाहरण:

 SELECT column_name(s) FROM table_name WHERE column_name BETWEEN value1 AND value2 

या

 SELECT column_name(s) FROM table_name WHERE column_name value1 >= column_name AND column_name =< value2 

आपको बस इतना करना होगा कि बस नीचे दिए गए कोड में हार्ड कोडित मान को बदल दिया गया है

 DECLARE @firstDate datetime DECLARE @secondDate datetime DECLARE @totalDays INT SELECT @firstDate = getDate() - 30 SELECT @secondDate = getDate() DECLARE @index INT SELECT @index = 0 SELECT @totalDays = datediff(day, @firstDate, @secondDate) CREATE TABLE #temp ( ID INT NOT NULL IDENTITY(1,1) ,CommonDate DATETIME NULL ) WHILE @index < @totalDays BEGIN INSERT INTO #temp (CommonDate) VALUES (DATEADD(Day, @index, @firstDate)) SELECT @index = @index + 1 END SELECT CONVERT(VARCHAR(10), CommonDate, 102) as [Date Between] FROM #temp DROP TABLE #temp 

अपने फ़ंक्शन का उपयोग करने से पहले, आपको एक "सहायक" तालिका सेट अप करने की आवश्यकता है, आपको प्रति डेटाबेस केवल एक बार करना होगा:

 CREATE TABLE Numbers (Number int NOT NULL, CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] DECLARE @x int SET @x=0 WHILE @x<8000 BEGIN SET @x=@x+1 INSERT INTO Numbers VALUES (@x) END 

यहाँ फ़ंक्शन है:

 CREATE FUNCTION dbo.ListDates ( @StartDate char(10) ,@EndDate char(10) ) RETURNS @DateList table ( Date datetime ) AS BEGIN IF ISDATE(@StartDate)!=1 OR ISDATE(@EndDate)!=1 BEGIN RETURN END INSERT INTO @DateList (Date) SELECT CONVERT(datetime,@StartDate)+n.Number-1 FROM Numbers n WHERE Number<=DATEDIFF(day,@StartDate,CONVERT(datetime,@EndDate)+1) RETURN END --Function 

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

 select * from dbo.ListDates('2010-01-01', '2010-01-13') 

उत्पादन:

 Date ----------------------- 2010-01-01 00:00:00.000 2010-01-02 00:00:00.000 2010-01-03 00:00:00.000 2010-01-04 00:00:00.000 2010-01-05 00:00:00.000 2010-01-06 00:00:00.000 2010-01-07 00:00:00.000 2010-01-08 00:00:00.000 2010-01-09 00:00:00.000 2010-01-10 00:00:00.000 2010-01-11 00:00:00.000 2010-01-12 00:00:00.000 2010-01-13 00:00:00.000 (13 row(s) affected) 

शायद अगर आप एक आसान तरीके से जाना चाहते हैं, तो ऐसा करना चाहिए।

 WITH date_range (calc_date) AS ( SELECT DATEADD(DAY, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP) - 6, 0) UNION ALL SELECT DATEADD(DAY, 1, calc_date) FROM date_range WHERE DATEADD(DAY, 1, calc_date) < CURRENT_TIMESTAMP) SELECT calc_date FROM date_range; 

लेकिन अस्थायी तालिका भी एक बहुत अच्छा तरीका है। शायद आप एक आबादी वाला कैलेंडर तालिका भी विचार करेंगे।

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

तारीखों की तालिका कैसे बनाएं (और एक संख्या तालिका बनाने का एक सुपर फास्ट रास्ता)

 /*Gets a list of integers into a temp table (Jeff Moden's idea from SqlServerCentral.com)*/ SELECT TOP 10950 /*30 years of days*/ IDENTITY(INT,1,1) as N INTO #Numbers FROM Master.dbo.SysColumns sc1, Master.dbo.SysColumns sc2 /*Create the dates table*/ CREATE TABLE [TableOfDates]( [fld_date] [datetime] NOT NULL, CONSTRAINT [PK_TableOfDates] PRIMARY KEY CLUSTERED ( [fld_date] ASC )WITH FILLFACTOR = 99 ON [PRIMARY] ) ON [PRIMARY] /*fill the table with dates*/ DECLARE @daysFromFirstDateInTheTable int DECLARE @firstDateInTheTable DATETIME SET @firstDateInTheTable = '01/01/1998' SET @daysFromFirstDateInTheTable = (SELECT (DATEDIFF(dd, @firstDateInTheTable ,GETDATE()) + 1)) INSERT INTO TableOfDates SELECT DATEADD(dd,nums.n - @daysFromFirstDateInTheTable, CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)) as FLD_Date FROM #Numbers nums 

अब जब आपके पास तिथियों की एक तालिका है, तो आप उनको तालिका प्राप्त करने के लिए केएम की तरह फ़ंक्शन (नहीं एपीसीसी) का उपयोग कर सकते हैं।

 CREATE FUNCTION dbo.ListDates ( @StartDate DATETIME ,@EndDate DATETIME ) RETURNS @DateList table ( Date datetime ) AS BEGIN /*add some validation logic of your own to make sure that the inputs are sound.Adjust the rest as needed*/ INSERT INTO @DateList SELECT FLD_Date FROM TableOfDates (NOLOCK) WHERE FLD_Date >= @StartDate AND FLD_Date <= @EndDate RETURN END 

एक बिट पार्टी के लिए देर हो चुकी है, लेकिन मुझे इस समाधान को थोड़ा सा पसंद है।

 CREATE FUNCTION ExplodeDates(@startDate DateTime, @endDate DateTime) RETURNS table as return ( SELECT TOP (DATEDIFF(DAY, @startDate, @endDate) + 1) DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @startDate) AS DATE FROM sys.all_objects a CROSS JOIN sys.all_objects b ) 
 Declare @date1 date = '2016-01-01' ,@date2 date = '2016-03-31' ,@date_index date Declare @calender table (D date) SET @date_index = @date1 WHILE @date_index<=@date2 BEGIN INSERT INTO @calender SELECT @date_index SET @date_index = dateadd(day,1,@date_index) IF @date_index>@date2 Break ELSE Continue END 

– ### छह में से एक आधा दर्जन का दूसरा एमएसएसक्यूएल को संभालने वाला एक और तरीका

 Declare @MonthStart datetime = convert(DateTime,'07/01/2016') Declare @MonthEnd datetime = convert(DateTime,'07/31/2016') Declare @DayCount_int Int = 0 Declare @WhileCount_int Int = 0 set @DayCount_int = DATEDIFF(DAY, @MonthStart, @MonthEnd) select @WhileCount_int WHILE @WhileCount_int < @DayCount_int + 1 BEGIN print convert(Varchar(24),DateAdd(day,@WhileCount_int,@MonthStart),101) SET @WhileCount_int = @WhileCount_int + 1; END; 

यदि आप किसी विशेष वर्ष से चालू वर्ष तक का समय प्रिंट करना चाहते हैं। बस स्वीकृत जवाब को बदल दिया।

 WITH mycte AS ( SELECT YEAR(CONVERT(DATE, '2006-01-01',102)) DateValue UNION ALL SELECT DateValue + 1 FROM mycte WHERE DateValue + 1 < = YEAR(GETDATE()) ) SELECT DateValue FROM mycte OPTION (MAXRECURSION 0) 

यह क्वेरी माइक्रोसॉफ्ट एसक्यूएल सर्वर पर काम करती है

 select distinct format( cast('2010-01-01' as datetime) + ( av / 10 ), 'yyyy-MM-dd' ) as aDate from ( SELECT ones.n + 10 * tens.n + 100 * hundreds.n + 1000 * thousands.n as v FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) hundreds(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thousands(n) ) a where format( cast('2010-01-01' as datetime) + ( av / 10 ), 'yyyy-MM-dd' ) < cast('2010-01-13' as datetime) order by aDate asc; 

अब देखते हैं कि यह कैसे काम करता है।

आंतरिक क्वेरी केवल 0 से 99 99 तक पूर्णांक की एक सूची देता है। यह तिथियों की गणना के लिए हमें 10,000 मूल्यों की एक सीमा प्रदान करेगा। आप दस_थीह हजारों और सौ-हजारों और इतने आगे के लिए पंक्तियां जोड़कर अधिक तिथियां पा सकते हैं।

 SELECT ones.n + 10 * tens.n + 100 * hundreds.n + 1000 * thousands.n as v FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) hundreds(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thousands(n) ) a; 

यह भाग एक तिथि में स्ट्रिंग को रूपांतरित करता है और इसमें आंतरिक क्वेरी से संख्या जोड़ता है।

 cast('2010-01-01' as datetime) + ( av / 10 ) 

फिर हम परिणाम को इच्छित प्रारूप में परिवर्तित कर देते हैं। यह भी स्तंभ का नाम है!

 format( cast('2010-01-01' as datetime) + ( av / 10 ), 'yyyy-MM-dd' ) 

इसके बाद हम केवल विशिष्ट मूल्यों को निकालकर कॉलम नाम को एडीएटी के उपनाम देते हैं।

 distinct format( cast('2010-01-01' as datetime) + ( av / 10 ), 'yyyy-MM-dd' ) as aDate 

हम उस सीमा का उपयोग करते हैं जहां आप चाहते हैं कि सीमा के भीतर केवल तिथियों में फ़िल्टर करें ध्यान दें कि हम यहां स्तंभ नाम का उपयोग करते हैं, चूंकि एसक्यूएल सर्वर स्तंभ उपनाम, एडीटी को स्वीकार नहीं करता है, जहां क्लॉज के भीतर

 where format( cast('2010-01-01' as datetime) + ( av / 10 ), 'yyyy-MM-dd' ) < cast('2010-01-13' as datetime) 

अन्त में, हम परिणामों को सॉर्ट करते हैं

  order by aDate asc; 

यदि आप मेरे जैसी स्थिति में हैं, जहां प्रक्रियाएं और कार्य निषिद्ध हैं और आपके एसक्यूएल उपयोगकर्ता को सम्मिलित करने की अनुमति नहीं है, इसलिए सम्मिलित न करें , "अस्थायी रूपों को सेट करें / घोषित करें जैसे कि @ सी की अनुमति नहीं है", लेकिन आप चाहते हैं किसी विशिष्ट अवधि में तारीखों की एक सूची तैयार करने के लिए , वर्तमान वर्ष में कुछ एकत्रीकरण करने के लिए कहें, इसका उपयोग करें

 select * from (select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from (select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, (select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, (select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, (select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, (select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v where gen_date between '2017-01-01' and '2017-12-31' 
 WITH TEMP (DIA, SIGUIENTE_DIA ) AS (SELECT 1, CAST(@FECHAINI AS DATE) FROM DUAL UNION ALL SELECT DIA, DATEADD(DAY, DIA, SIGUIENTE_DIA) FROM TEMP WHERE DIA < DATEDIFF(DAY, @FECHAINI, @FECHAFIN) AND DATEADD(DAY, 1, SIGUIENTE_DIA) <= CAST(@FECHAFIN AS DATE) ) SELECT SIGUIENTE_DIA AS CALENDARIO FROM TEMP ORDER BY SIGUIENTE_DIA 

विवरण तालिका दोहरी पर है लेकिन यदि आपकी डमी तालिका के लिए यह तालिका इस काम करता है

 SELECT dateadd(dd,DAYS,'2013-09-07 00:00:00') DATES INTO #TEMP1 FROM (SELECT TOP 365 colorder - 1 AS DAYS from master..syscolumns WHERE id = -519536829 order by colorder) a WHERE datediff(dd,dateadd(dd,DAYS,'2013-09-07 00:00:00'),'2013-09-13 00:00:00' ) >= 0 AND dateadd(dd,DAYS,'2013-09-07 00:00:00') <= '2013-09-13 00:00:00' SELECT * FROM #TEMP1 

उत्तर यहां avialbe है कैसे दो तिथियों के बीच सभी तिथियां सूचीबद्ध करें

 Create Procedure SelectDates(@fromDate Date, @toDate Date) AS BEGIN SELECT DATEADD(DAY,number,@fromDate) [Date] FROM master..spt_values WHERE type = 'P' AND DATEADD(DAY,number,@fromDate) < @toDate END 
 DECLARE @StartDate DATE = '2017-09-13', @EndDate DATE = '2017-09-16' SELECT date FROM ( SELECT DATE = DATEADD(DAY, rn - 1, @StartDate) FROM ( SELECT TOP (DATEDIFF(DAY, @StartDate, DATEADD(DAY,1,@EndDate))) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2 ORDER BY s1.[object_id] ) AS x ) AS y 

परिणाम:

 2017-09-13 2017-09-14 2017-09-15 2017-09-16