আমি 2 তারিখের সময় ক্ষেত্রের মধ্যে মাসের সংখ্যা গণনা করতে দেখছি।
ইউনিক্স টাইমস্ট্যাম্প পাওয়ার এবং 2 592 000 (সেকেন্ড) দ্বারা বিভাজক এবং মাইএসকিউএলকে গোল করার চেয়ে আরও ভাল উপায় কি আছে?
আমি 2 তারিখের সময় ক্ষেত্রের মধ্যে মাসের সংখ্যা গণনা করতে দেখছি।
ইউনিক্স টাইমস্ট্যাম্প পাওয়ার এবং 2 592 000 (সেকেন্ড) দ্বারা বিভাজক এবং মাইএসকিউএলকে গোল করার চেয়ে আরও ভাল উপায় কি আছে?
উত্তর:
DATEDIFF ফাংশন আপনি দুইটি তারিখের মধ্যে দিনের সংখ্যা দিতে পারেন। কোনটি আরও সঠিক, যেহেতু ... আপনি একটি মাসকে কীভাবে সংজ্ঞায়িত করবেন? (২৮, ২৯, ৩০, বা ৩১ দিন?)
PERIODDIFF
কেবলমাত্র YYYYMM মান লাগে, তাই আপনি যদি YYYYmm মানগুলি পাস করার আগে নিজে নিজে যে সমস্ত দিনগুলি হিসাব না করেন, তবে আপনি গণনা করছেন সমস্তই মাসের সংখ্যা, পুরো মাসের চেয়ে কম সংখ্যক মাস যদি থাকে তবে নিকটতম মাসে গোল হয়। জেনের উত্তর নীচে দেখুন।
PERIODDIFF
মন্তব্যের জন্য এতগুলি আপত্তি কেন ? পিরিয়ডডিফ দিনের মান গ্রহণ করে না, সুতরাং আপনি যদি পুরো সংখ্যক মাসের চেয়ে কম পরিমাণ থাকে তবে নিকটতম মাস পর্যন্ত গোলের মাসগুলি গণনা করছেন
আমি অবাক হয়েছি এখনও এর উল্লেখ করা হয়নি:
কটাক্ষপাত আছে TIMESTAMPDIFF () মাইএসকিউএল মধ্যে ফাংশন।
এটি আপনাকে যা করতে দেয় তা হ'ল দুটি TIMESTAMP
বা DATETIME
মানগুলিতে (বা DATE
মাইএসকিউএল স্বয়ংক্রিয়ভাবে রূপান্তরিত হবে) পাশাপাশি সময়ের সাথে আপনি নিজের পার্থক্যটিকে ভিত্তি করতে চান তার একক।
আপনি 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
এটি মূলত প্যারামিটার তালিকার প্রথম তারিখ থেকে কেটে যাওয়া মাসের সংখ্যা পায়। এই সমাধানটি স্বয়ংক্রিয়ভাবে প্রতি মাসে (২৮,৩০,৩১) দিনের বিভিন্ন পরিমাণের জন্য ক্ষতিপূরণ হিসাবে লিপ বছরগুলি বিবেচনায় নেওয়ার জন্য ক্ষতিপূরণ দেয় stuff আপনাকে কোনও স্টাফের বিষয়ে চিন্তা করতে হবে না।
আপনি যদি কেটে যাওয়া মাসের সংখ্যা দশমিক নির্ভুলতার পরিচয় দিতে চান তবে এটি আরও জটিল, তবে আপনি কীভাবে এটি করতে পারেন তা এখানে:
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
নির্বাচিত উত্তরের মন্তব্যের জন্য সমস্ত আপোডগুলি খুব মিস-লিডিং
PERIOD_DIFF দুটি তারিখের মধ্যে মাস গণনা করে।
উদাহরণস্বরূপ, আপনার_সেবায় এখন () এবং একটি সময় কলামের মধ্যে পার্থক্য গণনা করতে:
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
আমি পেরিওডিডিএফও ব্যবহার করি । তারিখের বছর এবং তারিখটি পেতে, আমি এক্সট্র্যাক্ট ফাংশনটি ব্যবহার করি :
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 মাস দীর্ঘ।
পুরো (সম্পূর্ণ) মাসের সংখ্যা পেতে , ব্যবহার করুন:
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 বছরেরও বেশি ব্যাপ্তির জন্য সঠিক। জেনের উত্তর স্পষ্টতই আরও নির্ভুল, তবে এটি আমার পছন্দ হিসাবে খুব ভার্জিক।
মাইএসকিউএল ম্যানুয়াল থেকে:
PERIOD_DIFF (পি 1, পি 2)
পি 1 এবং পি 2 পিরিয়ডের মধ্যে মাসের সংখ্যা ফেরত দেয়। পি 1 এবং পি 2 ওয়াইওয়াইএমএম বা ওয়াইওয়াইওয়াইএম আকারে থাকা উচিত। নোট করুন যে পিরিয়ড আর্গুমেন্ট P1 এবং P2 তারিখের মান নয়।
mysql> নির্বাচন করুন পেরিওড_ডিআইএফএফ (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;
যেখানে ডি 1 এবং ডি 2 হ'ল তারিখের এক্সপ্রেশন।
আমাকে যদি () স্টেটমেন্টটি ব্যবহার করতে হয় তা নিশ্চিত করতে যে মাসগুলি 2-র পরিবর্তে 02-এর মতো দুটি সংখ্যার সংখ্যা ছিল।
আমি এই উপায়ে পছন্দ করি, কারণ এভরিওন এটি প্রথম নজরে পরিষ্কারভাবে বুঝতে পারবে:
SELECT
12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
tab;
একটি ভাল উপায় আছে কি? হ্যাঁ. মাইএসকিউএল টাইমস্ট্যাম্প ব্যবহার করবেন না। তারা 36 বাইট দখল করে নিলেও এগুলি কাজ করা মোটেই সুবিধাজনক নয়। আমি মধ্য তারিখ থেকে জুলিয়ান ডেট এবং সেকেন্ডস ব্যবহার করে সমস্ত তারিখ / সময় মানের জন্য পুনরায় আদায় করব। এগুলি ইউনিক্সডেটটাইম গঠনের জন্য একত্রিত করা যেতে পারে। এটি যদি কোনও ডিডাবর্ডে (স্বাক্ষরযুক্ত 4 বাইট পূর্ণসংখ্যার) সঞ্চিত থাকে তবে 2106 অবধি সমস্ত তারিখগুলি এপোকের পর থেকে সেকেন্ড হিসাবে সংরক্ষণ করা যেতে পারে, 01/01/1970 DWORD সর্বাধিক ভাল = 4,294,967,295 - একটি DWord 136 বছর সেকেন্ড ধরে রাখতে পারে
তারিখ গণনা করার সময় জুলিয়ান তারিখগুলি কাজ করে খুব ভাল ইউনিক্সডেটটাইম মানগুলি তারিখ / সময় গণনা করার সাথে সাথে কাজ করা ভাল নয় তাকাতে ভাল হয় না, তাই যখন টাইমস্ট্যাম্পগুলি ব্যবহার করি যখন আমার একটি কলামের প্রয়োজন হবে যা আমি খুব বেশি গণনা করব না সহ, তবে আমি এক নজরে ইঙ্গিত চাই।
জুলিয়ান এবং পিছনে রূপান্তর খুব ভাল ভাষাতে খুব দ্রুত করা যেতে পারে। পয়েন্টার ব্যবহার করে আমার এটি প্রায় 900 টি ক্ল্কে নেমেছে (এটি অবশ্যই একটি STRING থেকে কোনও INTEGER তে রূপান্তর)
যখন আপনি মারাত্মক অ্যাপ্লিকেশনগুলিতে প্রবেশ করেন যা উদাহরণস্বরূপ আর্থিক বাজারগুলি যেমন তারিখ / সময় তথ্য ব্যবহার করে তখন জুলিয়ান তারিখগুলি ডি-ফ্যাক্টো।
ক্যোয়ারির মতো হবে:
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
গ্রাহক রেকর্ডে তৈরি ডেটস্ট্যাম্পের পর থেকে অনেকগুলি ক্যালেন্ডার মাস দেয়, মাইএসকিউএলকে অভ্যন্তরীণভাবে মাসে নির্বাচন করতে দেয়।
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
এই কোডটি কার্যকর করুন এবং এটি একটি ফাংশন তারিখ নির্ধারণ করবে যা আপনাকে তারিখের বিন্যাসে 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, ২০০৯'। এটি কি লিপ বছরের উপর নির্ভর করে # দিনের পরিষ্কার কাটা দ্বারা সংজ্ঞায়িত হয়- এটি কোন মাস, বা আগের মাসের একই দিন = 1 মাস month
দিনগুলির জন্য একটি গণনা :
ফেব্রুয়ারি 15 -> 29 (লিপ বছর) = 14 মার্চ 1, 2008 + 365 = মার্চ 1, ২০০৯. মার্চ 1 -> মার্চ 12 = 12 দিন। 14 + 365 + 12 = 391 দিন। মোট = 391 দিন / (মাসে গড় দিন = 30) = 13.03333 33
মাসের হিসাব :
ফেব্রুয়ারী 15 2008 - ফেব্রুয়ারি 15 2009 = 12 ফেব্রুয়ারি 15 -> মার্চ 12 = 1 মাসেরও কম কম = মোট 12 মাস, বা 13 ফেব্রুয়ারী 15 - মার্চ 12 'গত মাস' হিসাবে বিবেচিত
SELECT *
FROM emp_salaryrevise_view
WHERE curr_year Between '2008' AND '2009'
AND MNTH Between '12' AND '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
আপনি বছর, মাস এবং দিন এইভাবে পেতে পারেন:
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'
এটি কেবল দুটি তারিখ নেয় এবং তাদের মধ্যে মানগুলি পুনরুদ্ধার করে।