15

誕生日が次の 7 日以内にあるデータベースのユーザーを選択するクエリを作成しようとしています。

私は多くの研究を行いましたが、実用的な解決策を思い付くことができません。

誕生日フィールドは varchar として保存されます (例: '04/16/93')。これを処理する方法はありますか?

これは私がこれまでに持っているものです:

SELECT * 
FROM   `PERSONS` 
WHERE  `BIRTHDAY` > DATEADD(DAY, -7, GETDATE()) 

もっと明確にするべきでした。生年月日ではなく誕生日を見つけようとしています。だから私は年ではなく日と月を探しています。

4

18 に答える 18

52

次の 7 日間のすべての誕生日を取得するには、生年月日と今日の年差を生年月日に加算し、それが次の 7 日以内に収まるかどうかを調べます。

SELECT * 
FROM  persons 
WHERE  DATE_ADD(birthday, 
                INTERVAL YEAR(CURDATE())-YEAR(birthday)
                         + IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(birthday),1,0)
                YEAR)  
            BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY);

今日の誕生日を除外したい場合は>>=

SELECT * 
FROM  persons 
WHERE  DATE_ADD(birthday, 
                INTERVAL YEAR(CURDATE())-YEAR(birthday)
                         + IF(DAYOFYEAR(CURDATE()) >= DAYOFYEAR(birthday),1,0)
                YEAR)  
            BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY);

-- Same as above query with another way to exclude today's birthdays 
SELECT * 
FROM  persons 
WHERE  DATE_ADD(birthday, 
                INTERVAL YEAR(CURDATE())-YEAR(birthday)
                         + IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(birthday),1,0)
                YEAR) 
            BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY)
     AND DATE_ADD(birthday, INTERVAL YEAR(CURDATE())-YEAR(birthday) YEAR) <> CURDATE();


-- Same as above query with another way to exclude today's birthdays 
SELECT * 
FROM  persons 
WHERE  DATE_ADD(birthday, 
                INTERVAL YEAR(CURDATE())-YEAR(birthday)
                         + IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(birthday),1,0)
                YEAR) 
            BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY)
     AND (MONTH(birthday) <> MONTH(CURDATE()) OR DAY(birthday) <> DAY(CURDATE()));

ここにすべてのクエリのデモがあります

于 2013-09-11T17:50:37.670 に答える
12

その非常に簡単でシンプルです。if 条件などを使用する必要はなく、mysql の DATE_FORMAT() 関数を使用するだけで済みます。

これが私のSQLクエリです

SELECT id,email ,dob FROM `users` where DATE_FORMAT(dob, '%m-%d') >= DATE_FORMAT(NOW(), '%m-%d') and DATE_FORMAT(dob, '%m-%d') <= DATE_FORMAT((NOW() + INTERVAL +7 DAY), '%m-%d')

于 2018-05-31T06:10:23.953 に答える
6

これが私の解決策です。生年月日が 1 月 1 日で、今日の日付が 12 月 31 日の場合にも機能します。

SELECT `id`, `name`, `dateofbirth`,
    DATE_ADD(
        dateofbirth, 
        INTERVAL IF(DAYOFYEAR(dateofbirth) >= DAYOFYEAR(CURDATE()),
            YEAR(CURDATE())-YEAR(dateofbirth),
            YEAR(CURDATE())-YEAR(dateofbirth)+1
        ) YEAR
    ) AS `next_birthday`
FROM `user` 
WHERE 
    `dateofbirth` IS NOT NULL
HAVING 
    `next_birthday` BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY)
ORDER BY `next_birthday`
LIMIT 1000;
于 2015-01-17T13:41:13.283 に答える
2

これを試して:

 Select * From persons
 where (DayOfYear(birthday) >= 7 
         And DayOfYear(birthday) - DayOfYear(curdate()) Between 0 and 6) Or
       (MOD(YEAR(curDate()),4) = 0) And MOD(YEAR(curDate()),100) != 0
        And (DayOfYear(birthday) + 366 - DayOfYear(curdate())) % 366 < 7) Or
         (DayOfYear(birthday) + 365 - DayOfYear(curdate())) % 365 < 7)
于 2013-09-11T17:58:52.440 に答える
1

一定期間内に誕生日を控えている人のリストを取得しようとしているときに、いくつかの問題に遭遇する可能性があります。

うるう年がある場合、あなたが持っている条件がうるう年のケースを処理できない可能性があります。次の問題は今日のようなもので2016-12-30、次の 7 日間は b'days が必要です。したがって、期間の終わりは年2017です。この場合、いくつかの条件が失敗します。これらは非常に重要なテスト ケースです。

このスレッドで修正されたもののほとんどはDAYOFYEAR()、うるう年にあるときに失敗する を使用しています。

例えば。

DAYOFYEAR('2016-03-01 00:00:00')です61
DAYOFYEAR('2015-03-01 00:00:00')60

一番シンプルで分かりやすい方法がこれです。

  1. ユーザーの次の b'day を計算します。
  2. 次に、その日が範囲内にあるかどうかを確認します。

これはうるう年でも機能し、日付の範囲は 2 年にまたがります。

SELECT  * 
FROM    `PERSONS` 
WHERE  
    /* 
       Here we calculate the next coming b'day for user 
       and check if it is between our span 
    */
    CONCAT(IF( 
            CONCAT( YEAR(CURDATE()), substring(`BIRTHDAY`, 5, length(`BIRTHDAY`))) < CURDATE(), 
            YEAR(CURDATE()) + 1, /* Adds an year if already past */
            YEAR(CURDATE())  /* Use this year if it is upcoming */
         ), substring(`BIRTHDAY`, 5, length(`BIRTHDAY`))) 
    BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL @tot DAY)

PS: また、誕生日に基づいてこれらを注文したい場合にも最適なソリューションです。これをフィールドとして追加するだけです。

于 2016-04-13T12:56:05.727 に答える
1

次の 10 の誕生日 (今日の誕生日を含む) を表示しなければならないカレンダーに問題がありました。見つけたばかりのソリューションを関連する部分に減らしました。

SELECT first_name, last_name, birth_date,
    IF (DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T')) < DAYOFYEAR(DATE_FORMAT(NOW(),'1980-%m-%d %T')) ,
          DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T'))+368 ,
          DAYOFYEAR(DATE_FORMAT(birth_date,'1980-%m-%d %T'))) AS upcomming
FROM users
WHERE birth_date IS NOT NULL AND birth_date !=0
ORDER BY upcomming ASC 
LIMIT 0, 10

毎年(実年を含む)うるう年に設定されているので、問題はありません。年末に近づいても問題ありません。私は最終的に実用的な解決策を見つけることに非常に満足しているので、これを共有したかったのですが、おそらく他の誰かに役立つでしょう:)

PS: 今日の誕生日を表示したくない場合は、+1後に追加してくださいDAYOFYEAR(DATE_FORMAT(NOW(),'1980-%m-%d %T'))

于 2014-12-03T11:38:44.540 に答える
1

上記の Lobo からの受け入れられた回答には、クエリが 12 月 31 日に実行され、ユーザーの誕生日が 1 月 1 日である場合、一致しないという点で欠陥があります。

クエリにロジックを追加して、今年の誕生日が既に過ぎている場合は、今年ではなく来年の誕生日を見るようにする必要があります。以下の詳細:

SELECT *, IF( DAYOFYEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) < DAYOFYEAR( NOW() ),
DATE_ADD( STR_TO_DATE(birthday, '%m/%d/%Y'), INTERVAL YEAR( CURDATE() ) - YEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) + 1 YEAR ),
DATE_ADD( STR_TO_DATE(birthday, '%m/%d/%Y'), INTERVAL YEAR( CURDATE() ) - YEAR( STR_TO_DATE(birthday, '%m/%d/%Y') ) YEAR ) )
AS nextBirthday FROM persons
WHERE nextBirthday BETWEEN CURDATE() AND DATE_ADD( CURDATE(), INTERVAL 7 DAY);
于 2014-05-23T16:25:06.007 に答える
1

これは、同じ問題に直面したときに私がしたことです:

select * from users 
where ( month(date_of_birth) > month(CURDATE()) 
 and month(date_of_birth) < month(ADDDATE(CURDATE(),30)) ) 
 or ( month(CURDATE()) = month(date_of_birth) and day(date_of_birth) >= day(CURDATE()) 
 or month(ADDDATE(CURDATE(),30)) = month(date_of_birth) and day(date_of_birth) <= day(ADDDATE(CURDATE(),30)) ) 
 or ( year(CURDATE()) > year(ADDDATE(CURDATE(),30)) and month(date_of_birth) < month(CURDATE()) and month(date_of_birth) > month(ADDDATE(CURDATE(),30)) )
于 2015-02-06T19:53:09.610 に答える
0

この解決策はもっと簡単かもしれないと思います。

次のようなクエリ文字列を作成します(私はPHPとMySqlを使用しています)

$query = "SELECT cols FROM table WHERE MONTH(DobCol)= ".date('m')." AND (DAY(DobCol) >= ".date('d')." AND DAY(DobCol) <= ".(date('d')+$NumOfDaysToCheck).")";

次に、この $query を実行します。

于 2021-02-12T06:15:29.000 に答える