0

次の構造の MySQL テーブルがあります。

    id |    date    |  type   |     description
    ---------------------------------------------------
     0 | 1979-09-20 | 'bday'  | 'Birthday Employee1 '
     1 | 1984-05-04 | 'bday'  | 'Birthday Employee2 '
     2 | 1989-01-04 | 'bday'  | 'Birthday Employee3 '
     3 | 2013-10-10 | 'visit' | 'Visit of Visitor1  '

このテーブルは、従業員ポータルで今後発生するすべてのイベントと過去のイベントを処理する必要があります。イベントには 2 つの異なるタイプがあります。誕生日と訪問。これらは、列の型で文字列として宣言されます。誕生日は毎年ではなく 1 回だけ入力する必要があるため、このケースを処理するには複雑なクエリが必要です。

   SELECT * ,
   CASE type
   WHEN 'bday'
   THEN
     (CASE 
      WHEN ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )< NOW()
       THEN ADDDATE(ADDDATE(datum,INTERVAL YEAR(NOW())- YEAR(date) YEAR),
       INTERVAL 1 YEAR)
       ELSE ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
     END)
   ELSE date
   END 
   AS dates
   FROM events
   WHERE date > NOW() AND type='visit' OR ADDDATE(date, INTERVAL 
   YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
   ORDER BY dates ASC
   LIMIT 0 ,10

ネストされた case 句を括弧内に追加したため、このクエリは機能しません。次の行に置き換えました

   ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )

これは機能しましたが、ネストされた CASE 句でわかるように、問題は、最近の年にすでに行われた誕生日が選択されないことです。したがって、追加の CASE の目的は、年が 2013 年または 2014 年 (2013 年に既に行われている場合) のようになるかどうかを判断することです。

これは、年の最初の 2 週間の誕生日にとって非常に重要です。リマインダー通知は、前年にすでに表示されている必要があります。そうでない場合、あまり意味がありません。

実際には、ネストされた CASE 句が機能しない理由を理解する必要があります。これを解決するための明らかに簡単な方法がある可能性もありますが、現時点ではそれらを見ることができません。

4

2 に答える 2

1

「近い」将来のイベントや誕生日を表示したいと思います。1 つの方法は、ロジックを 3 つの部分とUNIONそれらに分割することです。3つの部分は次のとおりです。

  • 訪問
  • 今年の誕生日
  • 来年の誕生日

    ( SELECT id, date, type, description, 
             date AS dates
      FROM events
      WHERE type='visit' 
        AND date > NOW() 
    )
    UNION ALL
    ( SELECT id, date, type, description,
             ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR)
      FROM events
      WHERE type='bday'
        AND ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR) > NOW()
    )
    UNION ALL
    ( SELECT id, date, type, description,
             ADDDATE(date, INTERVAL (1+YEAR(NOW())-YEAR(date)) YEAR)
      FROM events
      WHERE type='bday'
    )
    ORDER BY dates ASC
    LIMIT 0, 10 ;
    

あなたCASEも正しいようです。ただし、すべての誕生日を考慮したい場合は、OR ADDDATE(date, INTERVAL YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'条件を単純なものに置き換える必要があります。OR type='bday'

于 2013-09-09T08:22:26.823 に答える
0

YEAR DIFF 部分を変更する必要があります。

SELECT ADDDATE(date, INTERVAL (FLOOR(DATEDIFF(CURDATE(),date)/365)) YEAR )<NOW()

id=0 の例

SELECT ADDDATE('1979-09-20', 
INTERVAL (FLOOR(DATEDIFF(CURDATE(),'1979-09-20')/365)) YEAR )< NOW();
于 2013-09-09T08:15:38.513 に答える