MySQL

2008-11-14 22 views
53

में तिथियों के बीच महीनों में अंतर मैं 2 दिनांक समय फ़ील्ड के बीच महीनों की संख्या की गणना करना चाहता हूं।MySQL

क्या यूनिक्स टाइमस्टैम्प और 2 592 000 (सेकेंड) द्वारा विभाजित करने और MySQL के साथ गोलाकार करने से बेहतर तरीका है?

उत्तर

16

DATEDIFF फ़ंक्शन आपको दो तिथियों के बीच दिनों की संख्या दे सकता है। जो अधिक सटीक है, क्योंकि ... आप एक महीने को कैसे परिभाषित करते हैं? (28, 2 9, 30, या 31 दिन?)

+48

[PERIODDIFF] (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_period-diff) महीनों की संख्या की सटीकता से गणना कर सकते हैं। –

+6

जब तारीखों की बात आती है तो "अधिक सटीक" अविश्वसनीय व्यक्तिपरक होता है। यदि, उदाहरण के लिए, आप ऐसे व्यवसाय में हैं जिनके मासिक चक्रों को यह जानने की आवश्यकता है कि दो तिथियों के बीच कितने महीने ऊपर हैं, जो आप ऊपर दिए गए कारणों के दिनों की तुलना में अधिक महत्वपूर्ण हो सकते हैं। एक महीने कितना समय है? अगर मुझे एक महीने की गिनती की ज़रूरत है तो मैं बस 30 से विभाजित नहीं कर सकता। –

+5

यह सही जवाब नहीं है; आपको [मैक्स] [http://stackoverflow.com/a/562477/389034) सही, नीचे जवाब देना चाहिए। अगर आप पूरे महीनों की संख्या, लीप वर्ष के लिए सही ढंग से लेखांकन और एक महीने के दिनों के भिन्न संख्या चाहते –

1

यह इस बात पर निर्भर करता है कि आप कैसे # महीनों को परिभाषित करना चाहते हैं। इन सवालों का जवाब दें: 'महीनों में क्या अंतर है: 15 फरवरी, 2008 - 12 मार्च, 200 9'। क्या यह स्पष्ट कट # दिनों द्वारा परिभाषित किया गया है जो लीप वर्षों पर निर्भर करता है- यह किस महीने है, या पिछले महीने = 1 महीने का उसी दिन।

एक गणना के दिन के लिए:

फ़र, 15 -> 29 (लीप वर्ष) = 14 मार्च 1, 2008 + 365 = मार्च 1, 2009 मार्च 1 -> मार्च 12 = 12 दिन। 14 + 365 + 12 = 3 9 1 दिन। कुल = 391 दिनों/(महीने में औसत दिन = 30) = 13,03333

महीने की गणना:

फ़र, 15 2008 - 15 फ़र, 2009 = 12 फ़र, 15 - से> मार्च 12 = कम 1 महीने कुल = 12 महीने, या 13 यदि फ़र, 15 - mar 12 'पिछले एक महीने'

7
MySQL मैनुअल से

माना जाता है:

PERIOD_DIFF (P1, P2)

अवधि पी 1 और पी 2 के बीच महीनों की संख्या देता है। पी 1 और पी 2 प्रारूप YYMM या YYYYMM प्रारूप में होना चाहिए। ध्यान दें कि अवधि तर्क P1 और P2 दिनांक मान नहीं हैं।

mysql> चयन PERIOD_DIFF (200802,200703); -> 11

तो यह कुछ इस तरह करना संभव हो सकता है:

Select period_diff(concat(year(d1),if(month(d1)<10,'0',''),month(d1)), concat(year(d2),if(month(d2)<10,'0',''),month(d2))) as months from your_table; 

कहाँ d1 और d2 तारीख अभिव्यक्तियां हैं।

मुझे लगता है कि महीनों था जैसे 02 के बजाय 2. से

1
SELECT * 
FROM emp_salaryrevise_view 
WHERE curr_year Between '2008' AND '2009' 
    AND MNTH Between '12' AND '1' 
6

एक दो अंकों की संख्या वहाँ एक बेहतर तरीका है सुनिश्चित करने के लिए करता है, तो() बयान का इस्तेमाल किया था? हां। MySQL Timestamps का उपयोग न करें। इस तथ्य के अलावा कि वे 36 बाइट्स पर कब्जा करते हैं, वे काम करने के लिए बिल्कुल सुविधाजनक नहीं हैं। मैं सभी दिनांक/समय मूल्यों के लिए मध्यरात्रि से जूलियन तिथि और सेकेंड का उपयोग कर चुका हूं। इन्हें यूनिक्सडेट टाइम बनाने के लिए जोड़ा जा सकता है।यदि यह किसी DWORD (हस्ताक्षरित 4 बाइट इंटीजर) में संग्रहीत है, तो 2106 तक की सभी जगहों को एपोक के बाद सेकेंड के रूप में संग्रहीत किया जा सकता है, 01/01/1970 DWORD अधिकतम वैल = 4,294,967,295 - एक DWORD 136 वर्ष सेकेंड

रख सकता है

जूलियन तिथियां बहुत जब तिथि गणना करने UNIXDateTime मूल्यों अच्छे हैं के साथ काम करने के लिए जब दिनांक/समय गणना करने के साथ काम करने में अच्छा कर रहे हैं न तो को देखने के लिए अच्छा कर रहे हैं, इसलिए मैं मुहर का उपयोग जब मैं एक स्तंभ की जरूरत है कि मैं लूंगा ज्यादा गणना नहीं कर रहे हैं, लेकिन मुझे एक नज़र में संकेत चाहिए।

जूलियन और पीछे कनवर्ट करना अच्छी भाषा में बहुत जल्दी किया जा सकता है। पॉइंटर्स का उपयोग करके मेरे पास लगभग 900 क्लिक्स हैं (यह एक STRING से एक इंटेग्रर के लिए एक रूपांतरण भी है)

जब आप गंभीर अनुप्रयोगों में शामिल होते हैं जो दिनांक/समय की जानकारी का उपयोग करते हैं उदाहरण के लिए वित्तीय बाजार, जूलियन तिथियां वास्तव में हैं।

+0

कहाँ क्या आपको 36 बाइट्स * पर कब्जा करने वाले तथ्य के बारे में जानकारी मिली है? MySQL मैन्युअल स्टेटस टाइमस्टैम्प कॉलम के लिए स्टोरेज आवश्यकता ** ** बाइट ** है। http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html Y2106 बग के लिए अब योजना बना शुरू – poncha

+0

! ;-) – ErichBSchulz

93

PERIOD_DIFF दो तिथियों के बीच महीनों की गणना करता है।

select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table; 
+1

किसी भी विचार क्या यह करता है जब यह 11 महीने और 1 दिन है, तो 12 महीने हो सकता है, लेकिन अगर आप 30 दिन महीने के लिए बदल तो यह अभी भी 11 होगी? –

+1

11 महीने और 1 दिन उपरोक्त उदाहरण के साथ 11 महीने वापस आ जाएगा। PERIOD_DIFF को 30 बनाम 31 दिन के महीनों का कोई मतलब नहीं है। –

3

क्वेरी किया जाएगा:

उदाहरण के लिए, your_table में) अब के बीच अंतर (और एक समय स्तंभ की गणना करने के

select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where.. 

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

-1

इस क्वेरी मेरे लिए काम किया :)

SELECT * FROM tbl_purchase_receipt 
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09' 

यह बस दो तिथियों लेने के लिए और उन दोनों के बीच मूल्यों प्राप्त करता है।

+0

पूरी तरह गलत जवाब है, वह महीनों की गिनती चाहता है –

7

मैं इस तरह से पसंद करते हैं, क्योंकि evryone यह पहली नज़र में स्पष्ट रूप से समझ जाएगा:

SELECT 
    12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months 
FROM 
    tab; 
2
DROP FUNCTION IF EXISTS `calcula_edad` $$ 
CREATE DEFINER=`root`@`localhost` FUNCTION `calcula_edad`(pFecha1 date, pFecha2 date, pTipo char(1)) RETURNS int(11) 
Begin 

    Declare vMeses int; 
    Declare vEdad int; 

    Set vMeses = period_diff(date_format(pFecha1, '%Y%m'), date_format(pFecha2, '%Y%m')) ; 

    /* Si el dia de la fecha1 es menor al dia de fecha2, restar 1 mes */ 
    if day(pFecha1) < day(pFecha2) then 
    Set vMeses = VMeses - 1; 
    end if; 

    if pTipo='A' then 
    Set vEdad = vMeses div 12 ; 
    else 
    Set vEdad = vMeses ; 
    end if ; 
    Return vEdad; 
End 

select calcula_edad(curdate(),born_date,'M') -- for number of months between 2 dates 
22

मैं भी PERIODDIFF का उपयोग करें।

SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table; 
+2

अविश्वसनीय! यह 50% कम समय का उपयोग करता है जो 'DATE_FORMAT' विधि, धन्यवाद! +1 –

+1

यहां एक यूनिक्स टाइमस्टैम्प 'चयन करें PERIOD_DIFF (एक्स्ट्राक्ट (अब से वर्ष()) (एक्स्ट्राक्ट (YROM_MONTH FROM_UNIXTIME (समय, "% Y% एम% डी"))) आपके_टेबल से महीनों के रूप में; – Smolla

+2

यह है गलत, 'PERIOD_DIFF' दिन मूल्य नहीं लेता है, इसलिए यदि आप महीनों की संख्या से कम है तो आप निकटतम महीने तक के महीनों की संख्या की गणना कर रहे हैं। इसे स्पष्ट करने के लिए आपको अपना उत्तर संपादित करना चाहिए। – rgvcorley

2

इस कोड को निष्पादित और यह एक समारोह datedeifference जो आप तिथि yyyy-mm-dd में अंतर दे देंगे पैदा करेगा: साल और तारीख के महीने प्राप्त करने के लिए, मैं समारोह EXTRACT का उपयोग करें। किसी भी दो तिथियों के बीच

DELIMITER $$ 

CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE 
NO SQL 

BEGIN 
    DECLARE dif DATE; 
    IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0 THEN 
       SET dif=DATE_FORMAT(
             CONCAT(
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
              '-', 
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
              '-', 
              DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))), 
             '%Y-%m-%d'); 
    ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN 
       SET dif=DATE_FORMAT(
             CONCAT(
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
              '-', 
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
              '-', 
              DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))), 
             '%Y-%m-%d'); 
    ELSE 
       SET dif=DATE_FORMAT(
             CONCAT(
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , 
              '-', 
              PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , 
              '-', 
              DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))), 
             '%Y-%m-%d'); 
    END IF; 

RETURN dif; 
END $$ 
DELIMITER; 
+1

क्या आपको लगता है कि आप साफ कर सकते हैं और अपने कोड को थोड़ा सा टिप्पणी कर सकते हैं, तो यह थोड़ा और समझ में आता है? धन्यवाद –

145

माह-अंतर:

मुझे आश्चर्य यह अभी तक का उल्लेख नहीं किया गया है कर रहा हूँ:

MySQL में TIMESTAMPDIFF() समारोह पर एक नज़र डालें।

इस तुम क्या करने की अनुमति देता है क्या दो TIMESTAMP या DATETIME मूल्यों (या यहां तक ​​कि DATE MySQL के रूप में होगा स्वतः-रूपांतरण) में पारित करने के साथ ही आप अपने अंतर का आधार चाहता हूँ समय की इकाई है।

आप पहले पैरामीटर में इकाई के रूप में MONTH निर्दिष्ट कर सकते हैं:

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04') 
-- Outputs: 0 


SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15') 
-- Outputs: 1 

SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16') 
-- Outputs: 7 

यह मूल रूप से नंबर प्राप्त करता है पैरामीटर सूची में पहली तारीख से महीने समाप्त हो गया। यह समाधान स्वचालित रूप से हर महीने (28,30,31) में दिनों की अलग-अलग राशि के साथ ही खाता लीप वर्ष — आपको लगता है कि सामान में से किसी के बारे में चिंता की जरूरत नहीं है को ध्यान में रखकर के लिए क्षतिपूर्ति। परिशुद्धता के साथ


माह-अंतर:

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

SELECT 
    TIMESTAMPDIFF(MONTH, startdate, enddate) + 
    DATEDIFF(
    enddate, 
    startdate + INTERVAL 
     TIMESTAMPDIFF(MONTH, startdate, enddate) 
    MONTH 
)/
    DATEDIFF(
    startdate + INTERVAL 
     TIMESTAMPDIFF(MONTH, startdate, enddate) + 1 
    MONTH, 
    startdate + INTERVAL 
     TIMESTAMPDIFF(MONTH, startdate, enddate) 
    MONTH 
) 

कहाँ startdate और enddate अपनी तिथि मापदंड हैं, चाहे वह एक स्क्रिप्ट से एक मेज इनपुट पैरामीटर में या के रूप में दो तारीख स्तंभों से हो:

उदाहरण:

वर्ष, महीने
With startdate = '2012-05-05' AND enddate = '2012-05-27': 
-- Outputs: 0.7097 

With startdate = '2012-05-05' AND enddate = '2012-06-13': 
-- Outputs: 1.2667 

With startdate = '2012-02-27' AND enddate = '2012-06-02': 
-- Outputs: 3.1935 
+3

यह सही उत्तर है, चयनित उत्तर पर 'PERIODDIFF' टिप्पणी के लिए सभी अपवॉट बहुत यादगार हैं – rgvcorley

+3

धन्यवाद, मेरे मामले में मुझे समावेशी तिथियों की आवश्यकता है, इसलिए मैं" date_add (enddate, अंतराल 1 दिन) "। फिर 2014-03-01 से 2014-05-31 2.97 –

+1

के बजाय 3.00 देगा, आपको बहुत धन्यवाद ....."सटीक के साथ माह अंतर" के लिए विशेष thanx: "। आप mysql का सितारा हैं – Vidhi

0

आप प्राप्त कर सकते हैं और दिन इस तरह से:

SELECT 
username 
,date_of_birth 
,DATE_FORMAT(CURDATE(), '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(CURDATE(), '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS years 
,PERIOD_DIFF(DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m')) AS months 
,DATEDIFF(CURDATE(),date_of_birth) AS days 
FROM users 
1

मैं परिशुद्धता के साथ महीने के अंतर की जरूरत है। हालांकि ज़ेन बिएन का समाधान सही दिशा में है, उसके दूसरे और तीसरे उदाहरण गलत परिणाम देती है। फरवरी में दिनों की संख्या से विभाजित फरवरी में एक दिन मई में एक दिन के बराबर नहीं है जो मई में दिनों की संख्या से विभाजित है। तो दूसरे उदाहरण चाहिए उत्पादन ((31-5 + 1)/31 + 13/30 =) 1,3043 और तीसरा उदाहरण ((29-27 + 1)/29 + 2/30 + 3 =) 3,1701।

SELECT 
    '2012-02-27' AS startdate, 
    '2012-06-02' AS enddate, 
    TIMESTAMPDIFF(DAY, (SELECT startdate), (SELECT enddate)) AS days, 
    IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), 0, (TIMESTAMPDIFF(DAY, (SELECT startdate), LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY))/DAY(LAST_DAY((SELECT startdate)))) AS period1,  
    TIMESTAMPDIFF(MONTH, LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY, LAST_DAY((SELECT enddate))) AS period2, 
    IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), (SELECT days), DAY((SELECT enddate)))/DAY(LAST_DAY((SELECT enddate))) AS period3, 
    (SELECT period1) + (SELECT period2) + (SELECT period3) AS months 
0

आप भी इस कोशिश कर सकते हैं:

मैं निम्न क्वेरी के साथ समाप्त हो गया

select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name; 

या

select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name; 
3

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

इन उदाहरणों को देखें: 1st जनवरी -> 31 वें जनवरी: यह 0 पूरे महीने है, और लगभग 1 महीने लंबे। 1 जनवरी -> 1 फरवरी? यह 1 महीना महीना है, और वास्तव में 1 महीने लंबा है।

पूरे महीनों की संख्या प्राप्त करने के लिए, का उपयोग करें:

SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31'); => 0 
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01'); => 1 

एक महीनों में गोल अवधि पाने के लिए आपको इस्तेमाल कर सकते हैं:

SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1 
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1 

यह करने के लिए सटीक है +/- 5 दिन और 1000 साल से अधिक के लिए श्रेणियों के लिए। जेन का जवाब स्पष्ट रूप से अधिक सटीक है, लेकिन यह मेरी पसंद के लिए भी वर्बोज़ है।