2

日付ごとに複数の行が存在しないように、日付列に UNIQUE キーを持つデータベース テーブルがあります。データベースに既に存在する日に新しい行を挿入する場合、「空き」日になるまで、後続の連続するすべての日付を 1 日戻します。

これが私が考えたことです:

INSERT INTO
 `activity`
 (`name`,`date`)
VALUES
 ('date 7','2009-07-31')
ON DUPLICATE KEY
 UPDATE `date` = DATE_ADD(`date`, INTERVAL '1' DAY)

私の考えでは、ON DUPLICATE KEY UPDATE はテーブルをバブルアップさせ、存在しない日になるまで、すべての日付に 1 日を追加し続けます。

たとえば、テーブルの内容が次のようになっている場合:

date 1, 2009-07-30
date 2, 2009-07-31
date 3, 2009-08-01
date 4, 2009-08-02
date 5, 2009-08-04 <- notice this date is two days past the previous one

…そして、2009 年 7 月 31 日の「日付 7」を挿入します。次のようにします。

date 1, 2009-07-30
date 7, 2009-07-31 <- newly inserted row
date 2, 2009-08-01 <- this and subsequent rows are all incremented
                      by one day until it hits a non-consecutive day
date 3, 2009-08-02
date 4, 2009-08-03
date 5, 2009-08-04 <- notice this date hasn't changed

しかし、重複キーの更新ではそのようには機能せず、衝突している行のみを更新し、その行が別の行と衝突すると、重複キーエラーで救済されます。

SQL だけでこの効果を達成するスマートな方法はありますか?

4

2 に答える 2

2

目標日以降の最初の空き日を照会します。これには、テーブルに後継者がいない日付を見つけるための左自己結合が含まれます。

SELECT DATE_ADD(Min(a.`date`), INTERVAL '1' DAY) AS `free_date`
FROM `activity` a
LEFT JOIN `activity` z
ON z.`date` = DATE_ADD(a.`date`, INTERVAL '1' DAY)
WHERE z.`date` IS NULL 
AND a.`date` >= '2009-07-31'

更新を実行して、目標日から最初の空き日までの範囲で各日付を増分します。

これで、希望するインサートの余地があります。

于 2010-11-26T22:26:03.617 に答える
0

更新を行う前に最大日付を選択し、最大日付に 1 日を追加します

そんな感じ:

重複キーについて

 UPDATE `date` = DATE_ADD(select max('date') from 'activity', INTERVAL '1' DAY)
于 2010-11-26T22:46:03.153 に答える