楽しかったです!OK、どうぞ。まず、いくつかの仮定に依存する簡単なバージョンを紹介します。
- 毎年、テーブルに少なくとも1つのエントリがあります
任意の年について、テーブルには毎週少なくとも1つあります。IE:このクエリは1から52までのすべての数値を返します:
your_tableからDISTINCT週を選択します
これらの制約を考えると、このクエリは必要なことを実行する必要があります。
INSERT INTO your_table (id, year, week, totals)
SELECT null, y, w, 0 FROM (
SELECT DISTINCT week w FROM your_table
) weeks
CROSS JOIN
(
SELECT DISTINCT year y FROM your_table
) years
WHERE
(y > (select min(year) from your_table) OR w > (select min(week) from your_table where `year`=y))
AND
(y < (select max(year) from your_table) OR w < (select max(week) from your_table where `year`=y))
AND
NOT EXISTS (select year, week from your_table where `year`=y AND `week`=w)
条件2が満たされない可能性がある場合-毎年欠落している週がある場合は、この行を置き換えることができます
SELECT DISTINCT week w FROM your_table
と
SELECT
(TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue + TWO_32.SeqValue) w
FROM
(SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 32 SeqValue) TWO_32
HAVING w >= 1 AND w <= 52
このより一般的なケースを与える:
INSERT INTO your_table (id, year, week, totals)
SELECT null, y, w, 0 FROM (
SELECT
(TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue + TWO_32.SeqValue) w
FROM
(SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 32 SeqValue) TWO_32
HAVING w >= 1 AND w <= 52
) weeks
CROSS JOIN
(
SELECT DISTINCT year y FROM your_table
) years
WHERE
(y > (select min(year) from your_table) OR w > (select min(week) from your_table where `year`=y))
AND
(y < (select max(year) from your_table) OR w < (select max(week) from your_table where `year`=y))
AND
NOT EXISTS (select year, week from your_table where `year`=y AND `week`=w)
(条件1が満たされない場合は、同様の手法を使用して年のリストを生成できますが、1年全体の穴がないことを推測しています。)
最後に、年と週に一意のインデックスがある場合、これは少し単純化できます。そのようなインデックスをまだ持っていない場合は、次のように作成できます。
ALTER TABLE `your_table` ADD CONSTRAINT date UNIQUE (
`year`,
`week`
)
必要に応じて、次のように、完了したら削除できます。
ALTER TABLE `your_table` DROP INDEX date;
その場合、where句の最後の部分を削除できます。
AND
NOT EXISTS (select year, week from your_table where `year`=y AND `week`=w)
INSERT IGNOREは、その一意の年/週の組み合わせがすでに存在する行をスキップするためです。
範囲生成コードに対するこの回答への称賛:https ://stackoverflow.com/a/8349837/160565