13

すべてのユーザーの誕生日を UNIX タイムスタンプとして保存しており、その日が誕生日のユーザーに毎日電子メールを送信したいと考えています。

今日の日付の誕生日を含むすべての行を取得する MySQL クエリを作成する必要があります。

これはかなり単純なはずですが、複雑にしすぎているだけかもしれません。

4

14 に答える 14

21

これはうまくいくはずです:

   SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
于 2010-02-07T21:24:50.527 に答える
9

これは、プロパティがうるう年を考慮に入れ、2 月 29 日が誕生日のユーザーと 3 月 1 日が同じユーザーを常に提供するという回答です。

SELECT * 
  FROM USERS
  WHERE 
     DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
     OR (
            (
                DATE_FORMAT(NOW(),'%Y') % 4 <> 0
                OR (
                        DATE_FORMAT(NOW(),'%Y') % 100 = 0
                        AND DATE_FORMAT(NOW(),'%Y') % 400 <> 0
                    )
            )
            AND DATE_FORMAT(NOW(),'%m-%d') = '03-01'
            AND DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'
        )
于 2010-02-07T22:08:11.647 に答える
4

これはますますコードゴルフの質問になるため、うるう年の処理を含むこれを解決するための私のアプローチは次のとおりです。

select * 
from user
where (date_format(from_unixtime(birthday),"%m-%d") = date_format(now(),"%m-%d"))
   or (date_format(from_unixtime(birthday),"%m-%d") = '02-29'
       and date_format('%m') = '02' 
       and last_day(now()) = date(now())
      );

説明: 最初の where 句は、誰かの誕生日が今日かどうかをチェックします。2 つ目は、現在の日が 2 月の最終日に等しい場合にのみ、誕生日が 2 月 29 日である人だけを選択するようにします。

例:

SELECT last_day('2009-02-01'); -- gives '2009-02-28'
SELECT last_day('2000-02-01'); -- gives '2009-02-29'
SELECT last_day('2100-02-01'); -- gives '2100-02-28'
于 2010-02-07T23:12:14.833 に答える
4

これはうるう年のケースをカバーする必要があり、内部の日付メカニズムを使用します。

基本的には、2 つの日付の間の年を生年月日に加算し、現在の日付と等しいかどうかをチェックします。

WHERE dob + INTERVAL (YEAR(CURDATE()) - YEAR(dob)) YEAR = CURDATE();

テスト:

SELECT '2012-02-29' 
       + INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-29')) YEAR 
       = '2015-02-28'; /* 1, is birthday */

SELECT '2012-02-28' 
       + INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-28')) YEAR  
       = '2015-02-28'; /* 1, is birthday */

SELECT '2012-02-28'
       + INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-28')) YEAR 
       = '2016-02-29'; /* 0, is NOT birthday  */

SELECT '2012-02-29'
       + INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-29')) YEAR 
       = '2016-02-29'; /* 1, is birthday */  
于 2015-10-01T16:21:56.543 に答える
2

私はこの問題に遭遇し、この単純なコードを使用してNOW();

$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";

結果は今日の誕生日なので、その後、誕生日にユーザーにメールを送信することに取り組んでいます。

私は DATE だけを使用してユーザーの誕生日を保存しているのでyy:mm:dd、常に .

于 2011-10-28T06:00:53.910 に答える
1

以下の答えは実際には機能しません。1 年が 365.24 日 (閏日である場合もある) であるという事実は考慮されていないため、ユーザーの生年月日との実際の比較は控えめに言っても複雑です。私は歴史的な理由でそれを残しています。

他の答えはうまくいくはずですが、行がたくさんある場合など、わずかな最適化が必要な場合はクエリをタイムスタンプ秒で直接表現する方がよいでしょう。リレーションを使用できます (タイムゾーンを考慮しているため、少し複雑です)。

today_starts = UNIX_TIMESTAMP(NOW()) - TIMESTAMPDIFF(SECOND, DATE(NOW()), NOW())
today_ends = today_starts + 86400

次に、タイムスタンプがそれらの値の間にあるレコードを選択します。

于 2010-02-07T21:27:49.537 に答える
1

これが私の貢献です

SELECT
  DAYOFYEAR(CURRENT_DATE)-(dayofyear(date_format(CURRENT_DATE,'%Y-03-01'))-60)=
  DAYOFYEAR(the_birthday)-(dayofyear(date_format(the_birthday,'%Y-03-01'))-60)
FROM
   the_table

ビット '(dayofyear(date_format(current_date,'%Y-03-01'))-60)' は、3 月 1 日が dayofyear 番号 61 になるため、うるう年には 1 を返し、通常の年には 0 を返します。

ここからは、余分な日を「私の誕生日」の計算から差し引くだけです。

于 2010-06-03T09:02:08.147 に答える
1

楽しみ :)

select p.birthday, 
CASE YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29 WHEN 0 THEN 1 ELSE 0 END as isBirthday29Feb,
CASE YEAR(now())%4  WHEN 0 THEN 1 ELSE 0 END as isThisYearLeap,
IF(YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29=0 AND YEAR(now())%4 != 0,
            DATE_ADD(DATE_ADD(p.birthday, INTERVAL 1  DAY), INTERVAL YEAR(NOW())-YEAR(p.birthday)  YEAR) ,
            DATE_ADD(p.birthday, INTERVAL YEAR(NOW())-YEAR(p.birthday)  YEAR)  
)as thisYearBirthDay
from person p;

これにより、現在の年に従って計算された人の誕生日が得られます。その後、他の計算に使用できます。列isBirthday28Febと列isThisYearLeapは、ソリューションを説明するためだけに与えられています。

于 2014-11-02T00:04:36.853 に答える
1

私はSaggi Malachiの答えを取り、その年にそのような日がない場合、2月29日の誕生日を2月28日の日付に含めるように拡張しました.

SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
UNION
SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(NOW(),'%Y')%4 != 0 AND DATE_FORMAT(NOW(),'%m-%d')='02-28' and DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'
于 2010-02-07T21:46:33.557 に答える
1

私はSaggiの答えを受け取り、次の7日間の誕生日を表示するように変更することを考えました.それはうるう年の問題もうまく解決することに気付きました:)

SELECT * 
   FROM USERS
   WHERE 
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') >= DATE_FORMAT(NOW(),'%m-%d') AND
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') <  DATE_FORMAT(NOW()+INTERVAL 1 DAY,'%m-%d')

上限は含まれていないことに注意してください。うるう年の場合、'02-28' と '02-29' の間には何もありませんが、うるう年以外の場合、'02-29' は '02-28' と '03-01' の間にあります。


次の 7 日間が必要な場合は、次を使用します。

SELECT * 
   FROM USERS
   WHERE 
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') BETWEEN
      DATE_FORMAT(NOW(),'%m-%d') AND DATE_FORMAT(NOW()+INTERVAL 7 DAY,'%m-%d')
于 2020-06-17T07:12:12.757 に答える
0
set @now=now();
select * from user where (month(birthday) = month(@now) and day(birthday) = day(@now)) or
  (month(birthday) = 2 and day(birthday) = 29 and month(@now) = 2 and day(@now) = 28 and
  month(date_add(@now, interval 1 day)) = 3);
于 2010-02-07T21:22:40.453 に答える
0

今日の日付に一致するすべての行を選択できませんでしたか? FROM_UNIXTIME() 関数を使用して UNIX タイムスタンプを日付に変換することもできます。

mysql> SELECT FROM_UNIXTIME(1196440219); -> '2007-11-30 10:30:19'

これはhttp://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtimeから文書化されています

于 2010-02-07T21:25:36.163 に答える