98

2 つの日時フィールド間の月数を計算しようとしています。

Unix タイムスタンプを取得し、2 592 000 (秒) で割り、MySQL 内で切り上げるよりも良い方法はありますか?

4

21 に答える 21

244

任意の2つの日付の月差:

これがまだ言及されていないことに驚いています:

MySQLのTIMESTAMPDIFF()関数を見てください。

これにより、2つTIMESTAMPまたはDATETIME値(またはDATEMySQLが自動変換する場合でも)と、差の基にする時間の単位を渡すことができます。

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
  )

テーブル内の2つの日付列からのものか、スクリプトからの入力パラメーターとしてかを問わず、日付パラメーターはどこ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
于 2012-07-30T07:14:21.773 に答える
108

PERIOD_DIFFは、2 つの日付の間の月を計算します。

たとえば、now() と your_table の time 列の差を計算するには、次のようにします。

select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
于 2009-02-18T19:27:37.457 に答える
32

PERIOD_DIFFも使用しています。日付の年と月を取得するには、関数 EXTRACTを使用します。

  SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
于 2011-03-01T20:02:05.700 に答える
18

DATEDIFF関数を使用すると、2 つの日付の間の日数を取得できます。月はどのように定義するのでしょうか? (28、29、30、または 31 日?)

于 2008-11-14T01:41:52.567 に答える
9

私はこの方法を好みます。

SELECT
    12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
    tab;
于 2010-08-20T09:27:21.400 に答える
8

MySQL マニュアルから:

PERIOD_DIFF(P1,P2)

期間 P1 と P2 の間の月数を返します。P1 と P2 は、YYMM または YYYYMM の形式である必要があります。期間引数 P1 および P2 は日付値ではないことに注意してください。

mysql> SELECT 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 は日付式です。

if() ステートメントを使用して、月が 2 ではなく 02 のような 2 桁の数字であることを確認する必要がありました。

于 2008-11-14T02:03:26.173 に答える
6

より良い方法はありますか?はい。MySQL タイムスタンプを使用しないでください。それらが 36 バイトを占有するという事実は別として、それらを操作するのはまったく便利ではありません。すべての日付/時刻値に、ユリウス日と真夜中からの秒を使用することをお勧めします。これらを組み合わせて UnixDateTime を形成できます。これが DWORD (符号なし 4 バイト整数) に格納されている場合、2106 年までの日付はエポック (1970 年 1 月 1 日) からの秒数として格納できます。

ユリウス日は、日付の計算を行う場合に非常に便利です UNIXDateTime 値は、日付/時刻の計算を行う場合に適しています どちらも見栄えがよくないので、あまり計算を行わない列が必要な場合はタイムスタンプを使用しますとありますが、一目で分かる表示が欲しいです。

Julian への変換とその逆の変換は、適切な言語で非常に迅速に行うことができます。ポインターを使用して、約 900 Clks まで下げました (もちろん、これは STRING から INTEGER への変換でもあります)。

金融市場などの日付/時刻情報を使用する本格的なアプリケーションを使用する場合、ユリウス日付が事実上使用されます。

于 2009-01-27T08:53:00.247 に答える
5

クエリは次のようになります。

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

MySQL が内部で月を選択できるように、顧客レコードに日付スタンプが作成されてからの暦月数を示します。

于 2009-09-08T21:48:00.147 に答える
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
于 2010-11-04T01:18:30.070 に答える
2

このコードを実行すると、日付形式 yyyy-mm-dd の違いを示す関数 datedeifference が作成されます。

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;
于 2011-07-25T15:32:06.370 に答える
1
SELECT * 
FROM emp_salaryrevise_view 
WHERE curr_year Between '2008' AND '2009' 
    AND MNTH Between '12' AND '1'
于 2009-01-27T07:43:08.063 に答える
1

正確な月差が必要でした。Zane Bien の解決策は正しい方向ですが、彼の 2 番目と 3 番目の例では不正確な結果が得られます。2 月の 1 日を 2 月の日数で割った値は、5 月の 1 日を 5 月の日数で割った値と等しくありません。したがって、2 番目の例では ((31-5+1)/31 + 13/30 = ) 1.3043 が出力され、3 番目の例では ((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
于 2017-05-25T01:41:54.277 に答える
1

これは、月数をどのように定義するかによって異なります。次の質問に答えてください: 「月の違いは何ですか: 2008 年 2 月 15 日 - 2009 年 3 月 12 日」。閏年に依存する明確な日数によって定義されますか-それは何月ですか、または前月の同じ日= 1か月です。

Days の計算:

2 月 15 日 -> 29 (閏年) = 14 2008 年 3 月 1 日 + 365 = 2009 年 3 月 1 日。3 月 1 日 -> 3 月 12 日 = 12 日。14 + 365 + 12 = 391 日。合計 = 391 日 / (月の平均日数 = 30) = 13.03333

月の計算:

2008 年 2 月 15 日 - 2009 年 2 月 15 日 = 12 2 月 15 日 -> 3 月 12 日 = 1 か月未満 合計 = 12 か月、または 2 月 15 日 - 3 月 12 日が「過去の 1 か月」と見なされる場合は 13 か月

于 2008-11-14T01:53:05.697 に答える
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
于 2014-06-06T12:44:32.530 に答える
-1

このクエリは私のために働いた:)

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

単純に 2 つの日付を取り、それらの間の値を取得します。

于 2010-05-09T09:57:36.820 に答える