मैं 2 दिनांक समय क्षेत्रों के बीच महीनों की संख्या की गणना करना चाह रहा हूं।
क्या यूनिक्स टाइमस्टैम्प प्राप्त करने और 2 592 000 (सेकंड) से विभाजित करने और व्हिटिन MySQL को गोल करने से बेहतर तरीका है?
जवाबों:
DateDiff समारोह आप दो तिथियों के बीच दिनों की संख्या दे सकते हैं। जो अधिक सटीक है, क्योंकि ... आप एक महीने को कैसे परिभाषित करते हैं? (२ 30, २ ९, ३०, या ३१ दिन?)
PERIODDIFF
बस एक YYYMM मान लेता है, इसलिए जब तक आप YYYMM मानों को पास करने से पहले खुद को दिनों के लिए खाते हैं, तो आप सभी की गणना कर रहे हैं महीनों की संख्या है, निकटतम महीने तक गोल किया जाता है अगर पूरे महीने से कम है। नीचे ज़ैन का जवाब देखें।
PERIODDIFF
टिप्पणी के लिए इतने सारे अपवित्र क्यों हैं ? पीरियडडिफ़ दिन के मूल्यों को नहीं लेता है, इसलिए आप महीनों की संख्या की गणना निकटतम महीने तक कर सकते हैं यदि महीने की पूरी संख्या से कम है
मुझे आश्चर्य है कि यह अभी तक उल्लेख नहीं किया गया है:
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-05')
-- Outputs: 1
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
PERIODDIFF
चयनित उत्तर पर टिप्पणी के लिए सभी upvotes बहुत मिस कर रहे हैं
PERIOD_DIFF दो तिथियों के बीच महीनों की गणना करता है।
उदाहरण के लिए, अब और () के बीच अंतर की गणना करने के लिए और अपने समय में कॉलम:
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
मैं भी PERIODDIFF का उपयोग करता हूं । साल और तारीख के महीने प्राप्त करने के लिए, मैं फ़ंक्शन का उपयोग EXTRACT :
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
DATE_FORMAT
विधि का 50% कम समय का उपयोग करता है, धन्यवाद! +1
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(time, "%Y%m%d"))) AS months FROM your_table;
PERIOD_DIFF
दिन के मूल्यों को नहीं लेता है, इसलिए यदि आप महीनों की संख्या की गणना कर रहे हैं, तो निकटतम माह तक हो सकता है, अगर पूरे महीने की संख्या कम है। इसे स्पष्ट करने के लिए आपको अपना उत्तर संपादित करना चाहिए।
यहाँ जितने भी उत्तर दिखाई देते हैं, 'सही' उत्तर वास्तव में आपकी ज़रूरत पर निर्भर करता है। मेरे मामले में, मुझे निकटतम पूरी संख्या में चक्कर लगाना होगा ।
इन उदाहरणों पर विचार करें: 1 जनवरी -> 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 साल से अधिक की सीमाओं के लिए सटीक है। ज़ैन का जवाब स्पष्ट रूप से अधिक सटीक है, लेकिन यह मेरी पसंद के लिए बहुत अधिक क्रिया है।
MySQL मैनुअल से:
PERIOD_DIFF (P1, P2)
पी 1 और पी 2 के बीच महीनों की संख्या लौटाता है। P1 और P2 प्रारूप YYMM या YYYMM में होना चाहिए। ध्यान दें कि पी 1 और पी 2 की अवधि तर्क तारीख मान नहीं है।
mysql> SELECT PERIOD_DIFF (200802,200703); -> ११
तो ऐसा कुछ करना संभव हो सकता है:
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 तारीख के भाव हैं।
मुझे यह सुनिश्चित करने के लिए कि () कथनों का उपयोग करना है, यह सुनिश्चित करने के लिए कि महीने 2 के बजाय 02 की तरह दो अंकों की संख्या थे।
मैं इस तरह से पसंद करता हूं, क्योंकि evryone इसे पहली नज़र में स्पष्ट रूप से समझ जाएगा:
SELECT
12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
tab;
क्या कोई बेहतर तरीका है? हाँ। MySQL टाइमस्टैम्प का उपयोग न करें। इस तथ्य के अलावा कि वे 36 बाइट्स पर कब्जा कर लेते हैं, वे साथ काम करने के लिए बिल्कुल भी सुविधाजनक नहीं हैं। मैं सभी तिथि / समय मानों के लिए आधी रात से जूलियन डेट और सेकंड्स का उपयोग करना चाहूंगा। इन्हें यूनिक्सडेटटाइम बनाने के लिए जोड़ा जा सकता है। यदि यह एक DWORD में संग्रहीत किया जाता है (4 बाइट इंटर्गर) तो तारीख 2106 तक सभी तरह से सेकंड के रूप में संग्रहीत किया जा सकता है, 01/01/1970 DWORD अधिकतम वैल = 4,294,967,295 - एक DWORD 136 साल का सेकंड रख सकता है
जूलियन डेट्स तारीख गणना करते समय काम करने के लिए बहुत अच्छी हैं। UNIXDateTime मान काम करने के लिए अच्छे हैं जब दिनांक / समय की गणना करते समय काम करना अच्छा होता है। के साथ, लेकिन मैं एक नज़र संकेत चाहते हैं।
जूलियन और बैक में कनवर्ट करना एक अच्छी भाषा में बहुत जल्दी किया जा सकता है। पॉइंटर्स का उपयोग करते हुए मैंने इसे लगभग 900 क्लिक्स में बदल दिया है (यह STRING से INTEGER के पाठ्यक्रम में रूपांतरण भी है)
जब आप गंभीर अनुप्रयोगों में आते हैं जो वित्तीय बाजारों उदाहरण के लिए दिनांक / समय की जानकारी का उपयोग करते हैं, तो जूलियन तिथियां वास्तविक हैं।
प्रश्न इस प्रकार होगा:
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
एक ग्राहक रिकॉर्ड पर बनाए गए डेटास्टैम्प के बाद से कई कैलेंडर महीने देता है, जिससे MySQL महीने का चयन आंतरिक रूप से करता है।
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
इस कोड को निष्पादित करें और यह एक फ़ंक्शन datedeifference बनाएगा जो आपको दिनांक प्रारूप yyyy-mm-dd में अंतर देगा।
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;
यह इस बात पर निर्भर करता है कि आप किस तरह से # महीनों की परिभाषा चाहते हैं। इस प्रश्न का उत्तर दें: 'महीनों में क्या अंतर है: फरवरी 15, 2008 - मार्च 12, 2009'। क्या यह उन दिनों के स्पष्ट कट द्वारा परिभाषित किया गया है जो लीप वर्ष पर निर्भर करता है- यह किस महीने का है, या पिछले महीने का एक ही दिन = 1 महीना।
दिनों के लिए एक गणना :
15 फरवरी -> 29 (लीप वर्ष) = 14 मार्च 1, 2008 + 365 = मार्च 1, 2009. मार्च 1 -> 12 मार्च = 12 दिन। 14 + 365 + 12 = 391 दिन। कुल = 391 दिन / (महीने में औसत दिन = 30) = 13.03333
महीनों की गणना :
फरवरी 15 2008 - फरवरी 15 2009 = 12 फरवरी 15 -> मार्च 12 = 1 महीने से कम कुल = 12 महीने, या 13 अगर फेब 15 - मार्च 12 को 'पिछला महीना' माना जाता है
मुझे सटीकता के साथ महीने-अंतर की आवश्यकता थी। हालाँकि ज़ेन बायन का समाधान सही दिशा में है, लेकिन उनके दूसरे और तीसरे उदाहरण गलत परिणाम देते हैं। फरवरी में एक दिन का विभाजन फरवरी में दिनों की संख्या से विभाजित होता है, मई में एक दिन के बराबर नहीं। तो दूसरा उदाहरण आउटपुट ((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
आप इस तरह से वर्ष, महीने और दिन प्राप्त कर सकते हैं:
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
आप यह भी आज़मा सकते हैं:
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;
इस क्वेरी ने मेरे लिए काम किया :)
SELECT * FROM tbl_purchase_receipt
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'
यह केवल दो तिथियां लेता है और उनके बीच के मूल्यों को पुनः प्राप्त करता है।