J'ai besoin d'une table MySQL pour contenir TOUTES LES DATES entre le 01/01/2011 et le 31/12/2011. J'ai créé un tableau avec une colonne nommée "_date", tapez DATE.
Avec quelle requête puis-je remplir le tableau avec toutes les dates souhaitées (au lieu d'avoir à les saisir à la main)?
Essaye ça:
DROP PROCEDURE IF EXISTS filldates;
DELIMITER |
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
WHILE dateStart <= dateEnd DO
INSERT INTO tablename (_date) VALUES (dateStart);
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;
|
DELIMITER ;
CALL filldates('2011-01-01','2011-12-31');
Voici le SQL Fiddle pour jouer avec lui: http://sqlfiddle.com/#!2/65d13/1
EDIT (pour vérifier si la date existe déjà) comme demandé par Andrew Fox .
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
DECLARE adate date;
WHILE dateStart <= dateEnd DO
SET adate = (SELECT mydate FROM MyDates WHERE mydate = dateStart);
IF adate IS NULL THEN BEGIN
INSERT INTO MyDates (mydate) VALUES (dateStart);
END; END IF;
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;//
Voici le SQL Fiddle pour jouer avec lui: http://sqlfiddle.com/#!2/66f86/1
si vous êtes dans une situation comme moi où les procédures sont interdites, et votre utilisateur sql n'a pas d'autorisations pour l'insertion, donc l'insertion n'est pas autorisée, mais vous voulez - générer une liste de dates dans une période spécifique, disons l'année en cours pour faire une agrégation, utilisez ceci
select * from
(select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where gen_date between '2017-01-01' and '2017-12-31'
J'ai trouvé cette variante coller-et-aller fonctionner:
DROP PROCEDURE IF EXISTS FillCalendar;
DROP TABLE IF EXISTS calendar;
CREATE TABLE IF NOT EXISTS calendar(calendar_date DATE NOT NULL PRIMARY KEY);
DELIMITER $$
CREATE PROCEDURE FillCalendar(start_date DATE, end_date DATE)
BEGIN
DECLARE crt_date DATE;
SET crt_date = start_date;
WHILE crt_date <= end_date DO
INSERT IGNORE INTO calendar VALUES(crt_date);
SET crt_date = ADDDATE(crt_date, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;
CALL FillCalendar('2013-01-01', '2013-01-03');
CALL FillCalendar('2013-01-01', '2013-01-07');
J'ai récemment eu besoin de créer un calendar_date
tableau comme ci-dessous:
CREATE TABLE `calendar_date` (
`date` DATE NOT NULL -- A calendar date.
, `day` SMALLINT NOT NULL -- The day of the year for the date, 1-366.
, `month` TINYINT NOT NULL -- The month number, 1-12.
, `year` SMALLINT NOT NULL -- The year.
, PRIMARY KEY (`id`));
Je l'ai ensuite renseigné avec toutes les dates possibles entre January 1, 2001
et December 31, 2100
(les deux inclus) en utilisant la requête ci-dessous:
INSERT INTO `calendar_date` (`date`
, `day`
, `month`
, `year`)
SELECT
DATE
, INCREMENT + 1
, MONTH(DATE)
, YEAR(DATE)
FROM
-- Generate all possible dates for every year from 2001 to 2100.
(SELECT
DATE_ADD(CONCAT(YEAR, '-01-01'), INTERVAL INCREMENT DAY) DATE
, INCREMENT
FROM
(SELECT
(UNITS + TENS + HUNDREDS) INCREMENT
FROM
(SELECT 0 UNITS UNION
SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION
SELECT 7 UNION SELECT 8 UNION SELECT 9) UNITS
CROSS JOIN
(SELECT 0 TENS UNION
SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION
SELECT 40 UNION SELECT 50 UNION SELECT 60 UNION
SELECT 70 UNION SELECT 80 UNION SELECT 90) TENS
CROSS JOIN
(SELECT 0 HUNDREDS UNION
SELECT 100 UNION SELECT 200 UNION SELECT 300 UNION
SELECT 400 UNION SELECT 500 UNION SELECT 600 UNION
SELECT 700 UNION SELECT 800 UNION SELECT 900) HUNDREDS
) INCREMENT
-- For every year from 2001 to 2100, find the number of days in the year.
, (SELECT
YEAR
, DAYOFYEAR(CONCAT(YEAR, '-12-31')) - DAYOFYEAR(CONCAT(YEAR, '-01-01')) + 1 DAYS
FROM
-- Generate years from 2001 to 2100.
(SELECT
(2000 + UNITS + TENS) YEAR
FROM
(SELECT 0 UNITS UNION
SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION
SELECT 7 UNION SELECT 8 UNION SELECT 9) UNITS
CROSS JOIN
(SELECT 0 TENS UNION
SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION
SELECT 40 UNION SELECT 50 UNION SELECT 60 UNION
SELECT 70 UNION SELECT 80 UNION SELECT 90) TENS
) YEAR
WHERE
YEAR BETWEEN 2001 AND 2100
) YEAR
WHERE
INCREMENT BETWEEN 0 AND DAYS - 1
ORDER BY
YEAR
, INCREMENT) DATE;
Sur ma base de données MySQL locale, la requête INSERT
n'a pris que quelques secondes. J'espère que cela aide quelqu'un.
Si vous avez une table avec un ensemble d'ID suffisamment contigu que vous pouvez utiliser -
INSERT INTO tablename (_date)
SELECT '2011-01-01' + INTERVAL (id - 1) DAY
FROM some_table_with_lots_of_ids
WHERE id BETWEEN 1 AND 365
note: mais sachez que cela pourrait vous causer des ennuis pendant les années bissextiles (avoir 366 jours)
Merci à moi et à. J'ai une meilleure solution qui vous permet de créer une table de calendrier spécifiée. Par exemple, si j'essaie de créer un tableau de 2014-04, cela ressemble à ceci:
SELECT (CURDATE() - INTERVAL c.number DAY) AS DATE
FROM
(
SELECT singles + tens + hundreds number FROM
(
SELECT 0 singles
UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) singles JOIN
(
SELECT 0 tens
UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30
UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60
UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90
) tens JOIN
(
SELECT 0 hundreds
UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300
UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600
UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900
) hundreds
ORDER BY number DESC
) c
WHERE c.number BETWEEN
DAYOFYEAR(NOW()) - DAYOFYEAR('2014-04-01')- DAY(LAST_DAY('2014-04-01')) +1
AND
DAYOFYEAR(NOW()) - DAYOFYEAR('2014-04-01')
Cela peut être réalisé en PHP en utilisant une boucle for simple. Il y a deux façons de le faire. Une façon serait de placer la date d'origine dans une variable et de faire exécuter la boucle à travers elle pour chaque jour en ajoutant +1 jour sur chaque boucle, par exemple, vous commencerez le 01/01/2011 puis la boucle ajoutera 0 la première fois, 1 jour la suivante, suivie de 2 jours ainsi de suite et ainsi de suite à la variable $ i. Vous pouvez ensuite imprimer les jours ou les ajouter à votre base de données. Dans ce cas, $ i représenterait le compteur avec 0 comme point de départ, <= 365 est le nombre de boucles que vous souhaitez parcourir qui est égal ou inférieur au nombre de jours et $ i ++ ajoute +1 à la variable $ i sur chaque boucle.
date ('Ymd' convertit la date en aaaa-mm-jj. L'utilisation d'un Y majuscule vous donne une année complète à 4 chiffres tandis que l'utilisation d'un minuscule y vous donnera les 2 derniers chiffres de l'année. Vous voulez la garder dans cette afin de l'ajouter dans un champ de date dans mySQL.
strtotime ($ originalDate analyse la date dans un horodatage Unix et le. "+". $ i. "day") ajoute essentiellement la valeur de $ i en jours à la date.
Enfin, il y a la requête mysqli. $ db représente la variable de connexion à la base de données, elle devra être remplacée par la variable que vous avez définie pour la connexion. Ceci est suivi de la requête réelle. Échangez simplement le tableau Word pour le nom de votre table et la date avant VALUES pour le nom de la ligne de date et vous êtes prêt à partir.
Ce qui suit est un exemple:
<?php
for($i=0;$i<=365;$i++){
$originalDate = "01/01/2011";
$date = date('Y-m-d',strtotime($originalDate . "+".$i." day"));
mysqli_query($db, "INSERT INTO table (date)VALUES('$date')");
}
Une autre façon d'y parvenir en utilisant la fonction for serait d'inclure les dates strtotime directement dans les actions for en opposition aux variables de compteur, ce qui est un morceau de code encore plus court. Remplacez $ i = 0 (le point de départ) par le point du jour de départ, suivez celui avec le point inférieur ou égal au point du jour de fin (le nombre de boucles) puis enfin avec votre plus +1 à la première instruction placée dans un variable prête à l'emploi.
Enfin, convertissez la date au format Y-m-d prêt à être placé dans la base de données et exécutez la requête.
Encore une fois, comme dans le premier exemple, cela peut être imprimé ou placé directement dans votre base de données.
Ce qui suit est un exemple:
<?php
for ($startdate = strtotime("2011-01-01"); $startdate <= strtotime("2011-12-31"); $startdate = strtotime("+1 day", $startdate)) {
$date= date("Y-m-d", $startdate);
mysqli_query($db, "INSERT INTO tracking (date)VALUES('$date')");
}
Je l'ai probablement rendu plus confus qu'il ne l'est, mais j'espère qu'il vous donnera au moins une idée de son fonctionnement.
Inspiré par le grand nombre d'IvanD, je viens à ceci:
SELECT DATE_ADD('2015-10-21', INTERVAL c.number DAY) AS DATE
FROM
(
SELECT singles + tens + hundreds+thousands number FROM
(
SELECT 0 singles
UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) singles JOIN
(
SELECT 0 tens
UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30
UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60
UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90
) tens JOIN
(
SELECT 0 hundreds
UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300
UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600
UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900
) hundreds
JOIN
(
SELECT 0 thousands
UNION ALL SELECT 1000 UNION ALL SELECT 2000 UNION ALL SELECT 3000
UNION ALL SELECT 4000 UNION ALL SELECT 5000 UNION ALL SELECT 6000
UNION ALL SELECT 7000 UNION ALL SELECT 8000 UNION ALL SELECT 9000
) thousands
ORDER BY number DESC
) c
WHERE c.number BETWEEN
0
AND
DATEDIFF('2016-10-08', '2015-10-21')
INSERT INTO my_dates (\`_date\`) SELECT DATE_ADD('2011-01-01', INTERVAL @_tmp:=@_tmp+1 day) \`_date\`
FROM (SELECT @_tmp:=-1 d UNION SELECT 1 UNION SELECT 2
UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a /\*10^1\*/
JOIN (SELECT 0 UNION SELECT 1 UNION SELECT 2
UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b /\*10^2\*/
JOIN (SELECT 0 UNION SELECT 1 UNION SELECT 2
UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c /\*10^3\*/
WHERE @_tmp+1 BETWEEN 0 AND DATEDIFF('2011-12-31', '2011-01-01');