दिनांक सीमा से दिन उत्पन्न करें


135

मैं एक क्वेरी की तरह चलाना चाहूंगा

select ... as days where `date` is between '2010-01-20' and '2010-01-24'

और वापसी डेटा जैसे:

दिन
----------
2010-01-20
2010-01-21
2010-01-22
2010-01-23
2010-01-24

10
इस प्रश्न से जुड़ी कोई अन्य समस्या नहीं है। उपरोक्त प्रश्न समस्या है, SQL पाठ्यक्रमों में महारत हासिल करना।
पेंटियम

क्या आपको किसी चयनित तिथि-सीमा के आधार पर तारीखों की एक सरणी की आवश्यकता है?
डेरेक अडैर

1
मैं एक उपयोग के बारे में सोच रहा हूँ, आपको एक समस्या खोजने के लिए ... यदि आपको अपनी तालिका में कुछ गुम रिकॉर्ड भरने का काम मिलता है। और आपको प्रत्येक दिन के लिए एक क्वेरी चलानी होगी जो मैं कुछ सोच रहा हूंinsert into table select ... as days date between '' and ''
Pentium10

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

1
@ यह ठीक है कि मैंने इस प्रश्न को क्यों बचाया। मुझे डेटा में कुछ लेफ्टिनेंट जॉइन करने की जरूरत है जो कुछ तिथियों के लिए मौजूद नहीं हो सकते।
जोश मरहल

जवाबों:


318

यह समाधान बिना छोरों, प्रक्रियाओं या अस्थायी तालिकाओं का उपयोग करता है । उपश्रेणी पिछले 10,000 दिनों के लिए तारीखें उत्पन्न करता है, और आपकी इच्छानुसार आगे या पीछे जाने के लिए बढ़ाया जा सकता है।

select a.Date 
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d
) a
where a.Date between '2010-01-20' and '2010-01-24' 

आउटपुट:

Date
----------
2010-01-24
2010-01-23
2010-01-22
2010-01-21
2010-01-20

प्रदर्शन पर नोट्स

यहाँ इसका परीक्षण करना , प्रदर्शन आश्चर्यजनक रूप से अच्छा है: उपरोक्त क्वेरी में 0.0009 सेकंड लगते हैं।

यदि हम उपकुंजियों का विस्तार लगभग उत्पन्न करते हैं। 100,000 संख्याएं (और इस प्रकार लगभग 274 साल की तारीखें), यह 0.0458 सेकंड में चलती हैं।

संयोग से, यह एक बहुत ही पोर्टेबल तकनीक है जो मामूली समायोजन के साथ अधिकांश डेटाबेस के साथ काम करती है।

SQL फिडेल उदाहरण 1,000 दिन लौटाता है


6
यदि आप बदलना बेहतर होगा कि तुम प्रदर्शन देखेंगे UNIONको UNION ALLडुप्लिकेट के लिए जाँच दूर करने के लिए ऐसा नहीं मौजूद यह बर्बाद कर समय -। हालांकि, यह IMO से अधूरा है - यदि आप UNIONs का उपयोग करके एक परिणाम का निर्माण करने जा रहे हैं, तो क्यों न केवल तारीख निर्दिष्ट करें और इसके साथ किया जाए?
OMG पॉनीज़

7
क्यों न केवल तारीख निर्दिष्ट करें और इसके साथ किया जाए - क्योंकि उपरोक्त विधि आपको बिना तालिका निर्माण की आवश्यकता के मनमाने ढंग से बड़े सेट (और तिथियां) बनाने की अनुमति देती है, जो आपके द्वारा सुझाए जा रहे तरीके से हार्ड-कोड के लिए दर्दनाक होगा। स्पष्ट रूप से 5 तारीखों के लिए यह ओवरकिल है; लेकिन फिर भी, यदि आप एक मेज के खिलाफ शामिल हो रहे हैं, जहां आपको पहले से तारीखों का पता नहीं है, लेकिन सिर्फ संभावित मिनट और अधिकतम मान, यह समझ में आता है।
RedFilter

2
आपके द्वारा पहले ही बनाए गए UNION स्टेटमेंट के स्थान पर DATETIME फ़ंक्शन का उपयोग करना "दर्दनाक" है? यह आपके द्वारा जोड़े जाने वाले तर्क की किसी भी आवश्यकता को कम करता है । इसलिए - आपने क्वेरी को ओवरक्लॉम्प किया है। UNION स्टेटमेंट, किसी भी तरह से, स्केलेबल नहीं है - किसी तिथि या संख्या को निर्दिष्ट करते हुए, जो इसे 20 या 30 तारीखों को समायोजित करने के लिए अपडेट करना चाहता है?
ओएमजी पोनीज

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

7
आप में से जो इस क्वेरी को काम नहीं कर सकते हैं: कृपया अपने आप को चेहरे पर थप्पड़ मारें और फिर इस क्वेरी को 1000 तारीखों के बारे में ओपी की टिप्पणी फिर से पढ़ें। चूंकि 2010 1000 दिन से अधिक पहले था, इसलिए आपको तदनुसार क्वेरी समायोजित करने की आवश्यकता होगी।
नोएल बैरन

32

यहाँ विचारों का उपयोग करते हुए एक और भिन्नता है:

CREATE VIEW digits AS
  SELECT 0 AS digit UNION ALL
  SELECT 1 UNION ALL
  SELECT 2 UNION ALL
  SELECT 3 UNION ALL
  SELECT 4 UNION ALL
  SELECT 5 UNION ALL
  SELECT 6 UNION ALL
  SELECT 7 UNION ALL
  SELECT 8 UNION ALL
  SELECT 9;

CREATE VIEW numbers AS
  SELECT
    ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number
  FROM
    digits as ones,
    digits as tens,
    digits as hundreds,
    digits as thousands;

CREATE VIEW dates AS
  SELECT
    SUBDATE(CURRENT_DATE(), number) AS date
  FROM
    numbers;

और फिर आप बस कर सकते हैं (देखें कि यह कितना सुंदर है?):

SELECT
  date
FROM
  dates
WHERE
  date BETWEEN '2010-01-20' AND '2010-01-24'
ORDER BY
  date

अपडेट करें

यह ध्यान देने योग्य है कि आप केवल वर्तमान तारीख से शुरू होने वाली पिछली तारीखों को उत्पन्न करने में सक्षम होंगे । यदि आप किसी प्रकार की दिनांक सीमा (पूर्व, भविष्य और बीच में) उत्पन्न करना चाहते हैं, तो आपको इस दृश्य का उपयोग करना होगा:

CREATE VIEW dates AS
  SELECT
    SUBDATE(CURRENT_DATE(), number) AS date
  FROM
    numbers
  UNION ALL
  SELECT
    ADDDATE(CURRENT_DATE(), number + 1) AS date
  FROM
    numbers;

1
यह सभी मामलों में काम नहीं करता है। दिनांक से तारीखों का चयन करें, जहां दिनांक '2014-12-01' और '2014-12-28' की तिथि के अनुसार दिनांक
vasanth

3
अच्छी कॉल @ user927258 ऐसा इसलिए है क्योंकि datesऊपर उल्लिखित पहला दृश्य वर्तमान तिथि से शुरू होने वाली तारीखों की गणना करता है, यही कारण है कि आप भविष्य में निर्धारित तिथियों को पुनः प्राप्त नहीं कर पाएंगे। @RedFilter का उत्तर समान डिज़ाइन दोष से ग्रस्त है। मैंने हालांकि अपने उत्तर में वर्कअराउंड जोड़ा है।
स्टीफन

कुछ विचारों का उपयोग निश्चित रूप से प्रश्नों को सरल करता है, और इसे पुन: प्रयोज्य बनाता है। यद्यपि वे अनिवार्य रूप से एक ही काम कर रहे हैं, उन सभी UNIONखंडों को एक एकल SQL कथन में अजीब लगता है।
स्टीवर्ट 16

24

स्वीकृत उत्तर PostgreSQL ("a" के पास या उसके समरूप त्रुटि) के लिए काम नहीं किया।

जिस तरह से आप PostgreSQL में करते generate_seriesहैं, वह फ़ंक्शन का उपयोग करके है, अर्थात:

SELECT day::date
FROM generate_series('2010-01-20', '2010-01-24', INTERVAL '1 day') day;

    day
------------
 2010-01-20
 2010-01-21
 2010-01-22
 2010-01-23
 2010-01-24
(5 rows)

14

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

with [dates] as (
    select convert(datetime, '1753-01-01') as [date] --start
    union all
    select dateadd(day, 1, [date])
    from [dates]
    where [date] < '9999-12-31' --end
)
select [date]
from [dates]
where [date] between '2013-01-01' and '2013-12-31'
option (maxrecursion 0)

Microsoft SQL Server 2005 पर, सभी संभावित दिनांक की CTE सूची जनरेट करने में 1:08 का समय लगा। एक सौ साल पैदा करने में एक सेकंड से भी कम समय लगा।


7

MSSQL क्वेरी

select datetable.Date 
from (
    select DATEADD(day,-(a.a + (10 * b.a) + (100 * c.a)),getdate()) AS Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a

    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b

    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) datetable
where datetable.Date between '2014-01-20' and '2014-01-24' 
order by datetable.Date DESC

उत्पादन

Date
-----
2014-01-23 12:35:25.250
2014-01-22 12:35:25.250
2014-01-21 12:35:25.250
2014-01-20 12:35:25.250

2
अगर मैंने केवल थोड़ा और नीचे स्क्रॉल किया होता ... आह। वैसे भी, धन्यवाद। मैंने अपने संस्करण पर समय निकालने के लिए एक CAST (<अभिव्यक्ति> AS DATE) जोड़ा। GETDATE () - 365 और GETDATE () के बीच में भी कहां उपयोग किया जाता है ... यदि आप आज अपनी क्वेरी चलाते हैं, तो यह कोई पंक्तियाँ नहीं देगा यदि आप WHERE = P में दिनांक नोट नहीं करते हैं
रिकार्डो C

4

एक लूप / कर्सर के बिना ऐसा करने के लिए पुराने स्कूल समाधान एक NUMBERSतालिका बनाना है , जिसमें 1 पर शुरू होने वाले मानों के साथ एक एकल इंटेगर कॉलम है।

CREATE TABLE  `example`.`numbers` (
  `id` int(10) unsigned NOT NULL auto_increment,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

आपको अपनी आवश्यकताओं को पूरा करने के लिए पर्याप्त रिकॉर्ड के साथ तालिका को आबाद करने की आवश्यकता है:

INSERT INTO NUMBERS (id) VALUES (NULL);

एक बार आपके पास NUMBERSमेज है, तो आप उपयोग कर सकते हैं:

SELECT x.start_date + INTERVAL n.id-1 DAY
  FROM NUMBERS n
  JOIN (SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d') AS start_date 
          FROM DUAL) x
 WHERE x.start_date + INTERVAL n.id-1 DAY <= '2010-01-24'

पूर्ण निम्न-तकनीकी समाधान होगा:

SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d')
 FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-21', '%Y-%m-%d')
 FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-22', '%Y-%m-%d')
 FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-23', '%Y-%m-%d')
 FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-24', '%Y-%m-%d')
 FROM DUAL

आप इसके लिए क्या उपयोग करेंगे?


तारीखों या संख्याओं की सूचियों को उत्पन्न करने के लिए LEFT JOIN करें। आप यह देखना चाहेंगे कि डेटा में कहाँ अंतराल हैं, क्योंकि आप अनुक्रमिक डेटा की सूची में लेफ्टिनेंट शामिल हैं - शून्य मान यह स्पष्ट कर देगा कि अंतराल कहाँ मौजूद है।


1
DUALतालिका एक खड़े में तालिका में के रूप में उपयोग करने के लिए ओरेकल और MySQL के द्वारा समर्थित है FROMखंड। इसका कोई अस्तित्व नहीं है, इसमें से मानों का चयन करना जो भी मूल्य है वापस कर देगा। इस विचार में स्टैंड-इन था, क्योंकि एक सेलेक्ट क्वेरी के लिए FROMकम से कम एक तालिका निर्दिष्ट करने वाले क्लॉज़ की आवश्यकता होती है ।
ओएमजी पोनीज

1
+1 वास्तव में RDBMS बनाने के बजाय एक स्थायी संख्या तालिका बनाने के लिए इसे हर बार जब आपको क्वेरी की आवश्यकता होती है, तब बनाते हैं। सहायक तालियाँ बुराई नहीं हैं, लोग!
बेकन

4

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

DUAL नामक तालिका बनाएं (Oracle DUAL तालिका कैसे काम करती है) के समान

  • आईडी (AutoNumber)
  • डमीक्लायम (पाठ)
  • एक पंक्ति मान जोड़ें (1, "डमीरो")

"ZeroThru9Q" नामक एक क्वेरी बनाएं; मैन्युअल रूप से निम्न सिंटैक्स दर्ज करें:

SELECT 0 AS a
FROM dual
UNION ALL
SELECT 1
FROM dual
UNION ALL
SELECT 2
FROM dual
UNION ALL
SELECT 3
FROM dual
UNION ALL
SELECT 4
FROM dual
UNION ALL
SELECT 5
FROM dual
UNION ALL
SELECT 6
FROM dual
UNION ALL
SELECT 7
FROM dual
UNION ALL
SELECT 8
FROM dual
UNION ALL
SELECT 9
FROM dual;

"TodayMinus1KQ" नामक एक क्वेरी बनाएं (आज से पहले की तारीखों के लिए); मैन्युअल रूप से निम्न सिंटैक्स दर्ज करें:

SELECT date() - (a.a + (10 * b.a) + (100 * c.a)) AS MyDate
FROM
  (SELECT *
   FROM ZeroThru9Q) AS a,

  (SELECT *
   FROM ZeroThru9Q) AS b,

  (SELECT *
   FROM ZeroThru9Q) AS c

"TodayPlus1KQ" नामक एक क्वेरी बनाएं (आज के बाद की तारीखों के लिए); मैन्युअल रूप से निम्न सिंटैक्स दर्ज करें:

SELECT date() + (a.a + (10 * b.a) + (100 * c.a)) AS MyDate
FROM
  (SELECT *
   FROM ZeroThru9Q) AS a,

  (SELECT *
   FROM ZeroThru9Q) AS b,

  (SELECT *
   FROM ZeroThru9Q) AS c;

"TodayPlusMinus1KQ" नाम की एक यूनियन क्वेरी बनाएं (दिनांक +/- 1000 दिनों के लिए):

SELECT MyDate
FROM TodayMinus1KQ
UNION
SELECT MyDate
FROM TodayPlus1KQ;

अब आप क्वेरी का उपयोग कर सकते हैं:

SELECT MyDate
FROM TodayPlusMinus1KQ
WHERE MyDate BETWEEN #05/01/2014# and #05/30/2014#

3

प्रक्रिया + अस्थायी तालिका:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `days`(IN dateStart DATE, IN dateEnd DATE)
BEGIN

    CREATE TEMPORARY TABLE IF NOT EXISTS date_range (day DATE);

    WHILE dateStart <= dateEnd DO
      INSERT INTO date_range VALUES (dateStart);
      SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);
    END WHILE;

    SELECT * FROM date_range;
    DROP TEMPORARY TABLE IF EXISTS date_range;

END

3

Thx Pentium10 - आपने मुझे स्टैकओवरफ़्लो में शामिल कर लिया :) - यह msaccess के लिए मेरा पोर्टिंग है - यह सोचें कि यह किसी भी संस्करण के साथ काम करेगा:

SELECT date_value
FROM (SELECT a.espr1+(10*b.espr1)+(100*c.espr1) AS integer_value,
dateadd("d",integer_value,dateserial([start_year], [start_month], [start_day])) as date_value
FROM (select * from 
    (
    select top 1 "0" as espr1 from MSysObjects
    union all
    select top 1 "1" as espr2 from MSysObjects
    union all
    select top 1 "2" as espr3 from MSysObjects
    union all
    select top 1 "3" as espr4 from MSysObjects
    union all
    select top 1 "4" as espr5 from MSysObjects
    union all
    select top 1 "5" as espr6 from MSysObjects
    union all
    select top 1 "6" as espr7 from MSysObjects
    union all
    select top 1 "7" as espr8 from MSysObjects
    union all
    select top 1 "8" as espr9 from MSysObjects
    union all
    select top 1 "9" as espr9 from MSysObjects
    ) as a,
    (
    select top 1 "0" as espr1 from MSysObjects
    union all
    select top 1 "1" as espr2 from MSysObjects
    union all
    select top 1 "2" as espr3 from MSysObjects
    union all
    select top 1 "3" as espr4 from MSysObjects
    union all
    select top 1 "4" as espr5 from MSysObjects
    union all
    select top 1 "5" as espr6 from MSysObjects
    union all
    select top 1 "6" as espr7 from MSysObjects
    union all
    select top 1 "7" as espr8 from MSysObjects
    union all
    select top 1 "8" as espr9 from MSysObjects
    union all
    select top 1 "9" as espr9 from MSysObjects
    ) as b,
    (
    select top 1 "0" as espr1 from MSysObjects
    union all
    select top 1 "1" as espr2 from MSysObjects
    union all
    select top 1 "2" as espr3 from MSysObjects
    union all
    select top 1 "3" as espr4 from MSysObjects
    union all
    select top 1 "4" as espr5 from MSysObjects
    union all
    select top 1 "5" as espr6 from MSysObjects
    union all
    select top 1 "6" as espr7 from MSysObjects
    union all
    select top 1 "7" as espr8 from MSysObjects
    union all
    select top 1 "8" as espr9 from MSysObjects
    union all
    select top 1 "9" as espr9 from MSysObjects
    ) as c   
)  as d) 
WHERE date_value 
between dateserial([start_year], [start_month], [start_day]) 
and dateserial([end_year], [end_month], [end_day]);

संदर्भित MSysObjects सिर्फ 'कारण एक्सेस के लिए टेबल काउंटिन की जरूरत है' कम से कम 1 रिकॉर्ड, क्लॉज से - कम से कम 1 रिकॉर्ड वाली कोई भी टेबल क्या करेगी।


2

जैसा कि पहले ही दिए गए कई अद्भुत उत्तरों में कहा गया है (या कम से कम इसकी पुष्टि की गई है), इस समस्या को आसानी से हल कर लिया जाता है जब आपके पास काम करने के लिए संख्याओं का एक सेट होता है।

नोट: निम्नलिखित टी-एसक्यूएल है, लेकिन यह केवल सामान्य अवधारणाओं का मेरा विशेष रूप से कार्यान्वयन है जो पहले से ही यहां और इंटरनेट पर बड़े पैमाने पर उल्लिखित है। कोड को अपनी पसंद की बोली में बदलना अपेक्षाकृत सरल होना चाहिए।

कैसे? इस प्रश्न पर विचार करें:

SELECT DATEADD(d, N, '0001-01-22')
FROM Numbers -- A table containing the numbers 0 through N
WHERE N <= 5;

उपरोक्त तिथि सीमा 1/22/0001 - 1/27/0001 उत्पन्न करती है और यह अत्यंत तुच्छ है। : वहाँ ऊपर क्वेरी में जानकारी के 2 प्रमुख टुकड़े हैं आरंभ तिथि की 0001-01-22और ऑफसेट की 5। यदि हम इन दोनों सूचनाओं को जोड़ते हैं तो स्पष्ट रूप से हमारी अंतिम तिथि है। इस प्रकार, दो तिथियों को देखते हुए, एक सीमा को उत्पन्न किया जा सकता है जैसे:

  • दो दी गई तारीखों (ऑफसेट), आसान के बीच अंतर खोजें:

    -- Returns 125 SELECT ABS(DATEDIFF(d, '2014-08-22', '2014-12-25'))

    ABS()यहाँ का उपयोग यह सुनिश्चित करता है कि तिथि क्रम अप्रासंगिक है।

  • संख्याओं का एक सीमित सेट उत्पन्न करें, यह भी आसान है:

    -- Returns the numbers 0-2 SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1 FROM(SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A')

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

इन दोनों तरीकों को मिलाने से हमारी समस्या दूर हो जाएगी:

DECLARE @date1 DATE = '9001-11-21';
DECLARE @date2 DATE = '9001-11-23';

SELECT D = DATEADD(d, N, @date1)
FROM (
    SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
    FROM (SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A') S
) Numbers
WHERE N <= ABS(DATEDIFF(d, @date1, @date2));

उपरोक्त उदाहरण भयानक कोड है, लेकिन यह दर्शाता है कि सब कुछ एक साथ कैसे आता है।

ज्यादा मस्ती

मुझे इस तरह का काम करने की ज़रूरत है इसलिए मैंने तर्क को दो टीवीएफ में बदल दिया। पहला संख्याओं की एक सीमा उत्पन्न करता है और दूसरा इस कार्यक्षमता का उपयोग तिथियों की एक श्रृंखला उत्पन्न करने के लिए करता है। गणित यह सुनिश्चित करने के लिए है कि इनपुट ऑर्डर मायने नहीं रखता और क्योंकि मैं उपलब्ध संख्याओं की पूरी श्रृंखला का उपयोग करना चाहता था GenerateRangeSmallInt

निम्न कार्य 65536 दिनांक की अधिकतम सीमा को वापस करने के लिए ~ 16ms CPU समय लेता है।

CREATE FUNCTION dbo.GenerateRangeDate (   
    @date1 DATE,   
    @date2 DATE   
)   
RETURNS TABLE
WITH SCHEMABINDING   
AS   
RETURN (
    SELECT D = DATEADD(d, N + 32768, CASE WHEN @date1 <= @date2 THEN @date1 ELSE @date2 END)
    FROM dbo.GenerateRangeSmallInt(-32768, ABS(DATEDIFF(d, @date1, @date2)) - 32768)
);

GO

CREATE FUNCTION dbo.GenerateRangeSmallInt (
    @num1 SMALLINT = -32768
  , @num2 SMALLINT = 32767
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
    WITH Numbers(N) AS (
        SELECT N FROM(VALUES
            (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
          , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
        ) V (N)
    )
    SELECT TOP(ABS(CAST(@num1 AS INT) - CAST(@num2 AS INT)) + 1)
           N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN @num1 <= @num2 THEN @num1 ELSE @num2 END - 1
    FROM Numbers A
       , Numbers B
);

2

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

SELECT TO_DATE('20160210','yyyymmdd') - 1 + LEVEL AS start_day 
from DUAL
connect by level <= (TO_DATE('20160228','yyyymmdd') + 1) - TO_DATE('20160210','yyyymmdd') ;

2

आप एक तिथि सीमा प्राप्त करना चाहते हैं।

अपने उदाहरण में आप '2010-01-20' और '2010-01-24' के बीच की तारीखें प्राप्त करना चाहेंगे

संभावित समाधान:

 select date_add('2010-01-20', interval row day) from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
    (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
    (SELECT @row:=-1) r
 ) sequence
 where date_add('2010-01-20', interval row day) <= '2010-01-24'

व्याख्या

MySQL के पास date_add फ़ंक्शन है

select date_add('2010-01-20', interval 1 day)

तुम्हे दूंगा

2010-01-21

दिनांकित फ़ंक्शन आपको अक्सर यह बताएगा कि आपको इसे दोहराना होगा

select datediff('2010-01-24', '2010-01-20')

जो लौटता है

 4

डेट रेंज में तारीखों की सूची प्राप्त करना पूर्णांक संख्याओं के अनुक्रम को बनाने के लिए उबलता है, देखें कि MySQL में पूर्णांक अनुक्रम उत्पन्न होता है

यहाँ सबसे अधिक उत्तोलित उत्तर ने आधार के रूप में https://stackoverflow.com/a/2652051/1497139 के समान दृष्टिकोण लिया है :

SELECT @row := @row + 1 as row FROM 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
(SELECT @row:=0) r
limit 4

जिसके परिणामस्वरूप होगा

row
1.0
2.0
3.0
4.0

पंक्तियों का उपयोग अब दिए गए प्रारंभ तिथि से तारीखों की सूची बनाने के लिए किया जा सकता है। शुरुआत की तारीख को शामिल करने के लिए हम पंक्ति -1 से शुरू करते हैं;

select date_add('2010-01-20', interval row day) from
 ( 
    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
    (SELECT @row:=-1) r
 ) sequence
 where date_add('2010-01-20', interval row day) <= '2010-01-24'

1

यदि आपको कभी अधिक की आवश्यकता होगी तो एक दो दिन, आपको एक तालिका की आवश्यकता होगी।

Mysql में एक तिथि सीमा बनाएँ

फिर,

select from days.day, count(mytable.field) as fields from days left join mytable on day=date where date between x and y;

3
आपने इसे क्यों पोस्ट किया है, क्योंकि उपरोक्त उत्तर के लिए तालिका की आवश्यकता नहीं है और समाधान प्रदान करता है?
पेंटियम

1

दो दिनांक फ़ील्ड के बीच दिनांक जनरेट करें

यदि आप SQL CTE क्वेरी से अवगत हैं, तो यह समाधान आपको अपना प्रश्न हल करने में मदद करेगा

यहाँ उदाहरण है

हमारे पास एक टेबल में तारीखें हैं

तालिका का नाम: "testdate"

STARTDATE   ENDDATE
10/24/2012  10/24/2012
10/27/2012  10/29/2012
10/30/2012  10/30/2012

परिणाम की आवश्यकता:

STARTDATE
10/24/2012
10/27/2012
10/28/2012
10/29/2012
10/30/2012

उपाय:

WITH CTE AS
  (SELECT DISTINCT convert(varchar(10),StartTime, 101) AS StartTime,
                   datediff(dd,StartTime, endTime) AS diff
   FROM dbo.testdate
   UNION ALL SELECT StartTime,
                    diff - 1 AS diff
   FROM CTE
   WHERE diff<> 0)
SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime
FROM CTE

स्पष्टीकरण: सीटीई रिकर्सिव क्वेरी स्पष्टीकरण

  • क्वेरी का पहला भाग:

    SELECT DISTINCT convert(varchar(10), StartTime, 101) AS StartTime, datediff(dd, StartTime, endTime) AS diff FROM dbo.testdate

    स्पष्टीकरण: Firstcolumn "startdate" है, दूसरा कॉलम दिनों में प्रारंभ और समाप्ति तिथि का अंतर है और इसे "diff" कॉलम माना जाएगा

  • क्वेरी का दूसरा भाग:

    UNION ALL SELECT StartTime, diff-1 AS diff FROM CTE WHERE diff<>0

    स्पष्टीकरण: यूनियन सभी उपरोक्त क्वेरी के परिणाम का परिणाम प्राप्त करेंगे, जब तक कि परिणाम शून्य नहीं हो जाता है, इसलिए "StartTime" परिणाम उत्पन्न CTE क्वेरी से विरासत में मिला है, और अंतर से, कमी - 1, इसलिए इसका स्वरूप 3, 2, और 1 जैसा दिखता है 0 तक

उदाहरण के लिए

STARTDATE   DIFF
10/24/2012  0
10/27/2012  0
10/27/2012  1
10/27/2012  2
10/30/2012  0

परिणाम विशिष्टता

STARTDATE       Specification
10/24/2012  --> From Record 1
10/27/2012  --> From Record 2
10/27/2012  --> From Record 2
10/27/2012  --> From Record 2
10/30/2012  --> From Record 3
  • प्रश्न का तीसरा भाग

    SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime FROM CTE

    यह "आरंभ" में दिन "अंतर" जोड़ देगा, इसलिए परिणाम नीचे के रूप में होना चाहिए

परिणाम

STARTDATE
10/24/2012
10/27/2012
10/28/2012
10/29/2012
10/30/2012

1

स्वीकार किए गए उत्तर की तुलना में छोटा, समान विचार:

(SELECT TRIM('2016-01-05' + INTERVAL a + b DAY) date
FROM
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9 ) d,
(SELECT 0 b UNION SELECT 10 UNION SELECT 20
UNION SELECT 30 UNION SELECT 40) m
WHERE '2016-01-05' + INTERVAL a + b DAY  <=  '2016-01-21')

1

जो कोई इसे सहेजे गए दृश्य के रूप में चाहता है (MySQL विचार में नेस्टेड चयन का समर्थन नहीं करता है):

create view zero_to_nine as
    select 0 as n union all 
    select 1 union all 
    select 2 union all 
    select 3 union all 
    select 4 union all 
    select 5 union all 
    select 6 union all 
    select 7 union all 
    select 8 union all 
    select 9;

create view date_range as
    select curdate() - INTERVAL (a.n + (10 * b.n) + (100 * c.n)) DAY as date
    from zero_to_nine as a
    cross join zero_to_nine as b
    cross join zero_to_nine as c;

आप तब कर सकते हैं

select * from date_range

लेना

date
---
2017-06-06
2017-06-05
2017-06-04
2017-06-03
2017-06-02
...

1

मारियाडीबी> = 10.3 और MySQL> = 8.0 में नए पुनरावर्ती (सामान्य टेबल एक्सप्रेशंस) कार्यक्षमता का उपयोग करते हुए सुरुचिपूर्ण समाधान।

WITH RECURSIVE t as (
    select '2019-01-01' as dt
  UNION
    SELECT DATE_ADD(t.dt, INTERVAL 1 DAY) FROM t WHERE DATE_ADD(t.dt, INTERVAL 1 DAY) <= '2019-04-30'
)
select * FROM t;

उपरोक्त '2019-01-01' और '2019-04-30' के बीच की तारीखों की एक तालिका देता है। यह शालीनता से तेज भी है। 1000 साल पुरानी तारीखें (~ 365,000 दिन) मेरी मशीन पर लगभग 400ms लगती हैं।


1

यह मक्खी पर इन तिथियों को उत्पन्न करने के साथ एक अच्छा विचार है। हालाँकि, मैं अपने आप को बहुत बड़ी रेंज के साथ करने के लिए सहज महसूस नहीं करता हूँ, इसलिए मैं निम्नलिखित समाधान के साथ समाप्त हो गया हूं:

  1. एक तालिका "डेटसन्यूट्स" बनाई, जो तारीखों की गणना के लिए इस्तेमाल किए गए संख्याओं को धारण करेगा:
CREATE TABLE DatesNumbers (
    i MEDIUMINT NOT NULL,
    PRIMARY KEY (i)
)
COMMENT='Used by Dates view'
;
  1. -59999 से 40000 तक की संख्या के साथ उपरोक्त तकनीकों का उपयोग करते हुए तालिका को आबाद किया। यह रेंज मुझे 59999 दिनों (~ 164 वर्ष) से ​​40000 दिनों (109 वर्ष) पीछे की तारीखें देगी:
INSERT INTO DatesNumbers
SELECT 
    a.i + (10 * b.i) + (100 * c.i) + (1000 * d.i) + (10000 * e.i) - 59999 AS i
FROM 
  (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a,
  (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b,
  (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c,
  (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d,
  (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
;
  1. एक दृश्य "दिनांक" बनाया गया:
SELECT
      i,
      CURRENT_DATE() + INTERVAL i DAY AS Date
FROM
    DatesNumbers

बस।

  • (+) प्रश्नों को पढ़ना आसान
  • (+) फ्लाई नंबर पीढ़ियों पर नहीं
  • (+) अतीत और भविष्य में तारीखें देता है और इस पद के लिए इस तरह देखने के लिए कोई यूनिअन नहीं है ।
  • (+) "अतीत में केवल" या "भविष्य में केवल" तिथियों का उपयोग कर फ़िल्टर किया जा सकता है WHERE i < 0या WHERE i > 0(पी)
  • (-) 'अस्थायी' तालिका और दृश्य का उपयोग किया जाता है

0

ठीक है .. इसे आज़माएँ: http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/
http://dev.mysql.com/doc/refman/5.0/en/ loop-statement.html
http://www.roseindia.net/sql/mysql-example/mysql-loop.shml

टेम्परेचर टेबल जेनरेट करने के लिए उसका उपयोग करें, कहें, और उसके बाद टेम्प टेबल पर सेलेक्ट करें। या एक समय में परिणाम एक।
जो आप कहते हैं कि आप करना चाहते हैं वह एक सेलेक्ट स्टेटमेंट के साथ नहीं किया जा सकता है , लेकिन यह MySQL के लिए विशिष्ट चीजों के साथ संभव हो सकता है।
तो फिर, शायद आपको अभिशाप चाहिए: http://dev.mysql.com/doc/refman/5.0/en/cursors.html


0

Oracle के लिए, मेरा समाधान है:

select trunc(sysdate-dayincrement, 'DD') 
  from dual, (select level as dayincrement 
                from dual connect by level <= 30)

Sysdate को विशिष्ट तिथि में बदला जा सकता है और अधिक दिनांक देने के लिए स्तर संख्या को बदला जा सकता है।


0

यदि आप दो तिथियों के बीच तारीखों की सूची चाहते हैं:

create table #dates ([date] smalldatetime)
while @since < @to
begin
     insert into #dates(dateadd(day,1,@since))
     set @since = dateadd(day,1,@since)
end
select [date] from #dates

* फिडल यहां: http://sqlfiddle.com/# -6 / 9eecb/ 3469


0
set language  'SPANISH'
DECLARE @table table(fechaDesde datetime , fechaHasta datetime ) 
INSERT @table VALUES('20151231' , '20161231');
WITH x AS 
    (
        SELECT   DATEADD( m , 1 ,fechaDesde ) as fecha  FROM @table
        UNION ALL
        SELECT  DATEADD( m , 1 ,fecha )
        FROM @table t INNER JOIN x ON  DATEADD( m , 1 ,x.fecha ) <= t.fechaHasta
    )
SELECT LEFT( CONVERT( VARCHAR, fecha , 112 ) , 6 ) as Periodo_Id 
,DATEPART ( dd, DATEADD(dd,-(DAY(fecha)-1),fecha)) Num_Dia_Inicio
,DATEADD(dd,-(DAY(fecha)-1),fecha) Fecha_Inicio
,DATEPART ( mm , fecha ) Mes_Id
,DATEPART ( yy , fecha ) Anio
,DATEPART ( dd, DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha))) Num_Dia_Fin
,DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha)) ultimoDia
,datename(MONTH, fecha) mes
,'Q' + convert(varchar(10),  DATEPART(QUARTER, fecha)) Trimestre_Name
FROM x 
OPTION(MAXRECURSION 0)

0
DELIMITER $$
CREATE PROCEDURE GenerateRangeDates(IN dateStart DATE, IN dateEnd DATE)
BEGIN

    CREATE TEMPORARY TABLE IF NOT EXISTS dates (day DATE);

    loopDate: LOOP
        INSERT INTO dates(day) VALUES (dateStart); 
        SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);

        IF dateStart <= dateEnd 
            THEN ITERATE loopDate;
            ELSE LEAVE loopDate;
        END IF;
    END LOOP loopDate;

    SELECT day FROM dates;
    DROP TEMPORARY TABLE IF EXISTS dates;

END 
$$

-- Call procedure
call GenerateRangeDates( 
        now() - INTERVAL 40 DAY,
        now()
    );

0

RedFilters शीर्ष समाधान का SQLite संस्करण

select d.Date
from (
    select 
    date(julianday('2010-01-20') + (a.a + (10 * b.a) + (100 * c.a))) as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) d
where 
d.Date between '2010-01-20' and '2010-01-24' 
order by d.Date

0

कार्यदिवस में सुधार के साथ पावरपॉइंट की तारीख तालिका https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23bbe90e के लिए एक कस्टम हॉलिडे टेबल Microsoft MSSQL 2012 में शामिल होना

with [dates] as (
    select convert(datetime, '2016-01-01') as [date] --start
    union all
    select dateadd(day, 1, [date])
    from [dates]
    where [date] < '2018-01-01' --end
)
select [date]
, DATEPART (dw,[date]) as Wochentag
, (select holidayname from holidaytable 
where holidaytable.hdate = [date]) 
as Feiertag
from [dates]
where [date] between '2016-01-01' and '2016-31-12'
option (maxrecursion 0)

0
WITH
  Digits AS (SELECT 0 D 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),
  Dates AS (SELECT adddate('1970-01-01',t4.d*10000 + t3.d*1000 + t2.d*100 + t1.d*10 +t0.d) AS date FROM Digits AS t0, Digits AS t1, Digits AS t2, Digits AS t3, Digits AS t4)
SELECT * FROM Dates WHERE date BETWEEN '2017-01-01' AND '2017-12-31'

0

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

जैसे

2019-01-22 08:45:00
2019-01-22 09:00:00
2019-01-22 09:15:00
2019-01-22 09:30:00
2019-01-22 09:45:00
2019-01-22 10:00:00

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

CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_calendar_table`()
BEGIN

select unix_timestamp('2014-01-01 00:00:00') into @startts;
select unix_timestamp('2025-01-01 00:00:00') into @endts;

if ( @startts < @endts ) then

    DROP TEMPORARY TABLE IF EXISTS calendar_table_tmp;

    CREATE TEMPORARY TABLE calendar_table_tmp (ts int, dt datetime); 

    WHILE ( @startts < @endts)
        DO 
        SET @startts = @startts + 900;
        INSERT calendar_table_tmp VALUES (@startts, from_unixtime(@startts));
    END WHILE;

END if;

END

और फिर के माध्यम से हेरफेर

select ts, dt from calendar_table_tmp;

कि तुम भी ts दे

'1548143100', '2019-01-22 08:45:00'
'1548144000', '2019-01-22 09:00:00'
'1548144900', '2019-01-22 09:15:00'
'1548145800', '2019-01-22 09:30:00'
'1548146700', '2019-01-22 09:45:00'
'1548147600', '2019-01-22 10:00:00'

यहां से आप अन्य जानकारी जैसे कि जोड़ना शुरू कर सकते हैं

select ts, dt, weekday(dt) as wd from calendar_table_tmp;

या तालिका विवरण बनाने के साथ एक वास्तविक तालिका बनाएँ


0

एक अधिक सामान्य उत्तर जो एडब्ल्यूएस MySQL में काम करता है।

select datetable.Date
from (
    select date_format(adddate(now(),-(a.a + (10 * b.a) + (100 * c.a))),'%Y-%m-%d') AS Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a

    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b

    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
     union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) datetable
where datetable.Date between now() - INTERVAL 14 Day and Now()
order by datetable.Date DESC

-1

Mysql 8.0.1 और मारीडब 10.2.2 के लिए एक और समाधान पुनरावर्ती आम तालिका अभिव्यक्तियों का उपयोग कर रहा है:

with recursive dates as (
    select '2010-01-20' as date
    union all
    select date + interval 1 day from dates where date < '2010-01-24'
)
select * from dates;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.