2009-07-03 9 views
44

J'ai une table mysql avec des données liées aux dates. Chaque ligne a des données et une date, comme ceci:Mysql: Sélectionnez toutes les données entre deux dates

2009-06-25 75 
2009-07-01 100 
2009-07-02 120 

J'ai une requête mysql qui sélectionne toutes les données entre deux dates. Ceci est la requête:

SELECT data FROM tbl WHERE date BETWEEN date1 AND date2

Mon problème est que je dois aussi obtenir les lignes entre date1 et date2 même s'il n'y a pas de données pour un jour.

Donc, ma requête manquerait les dates vides entre le 2009-06-25 et le 2009-07-01.

Puis-je d'une certaine manière ajouter ces dates avec seulement 0 comme données?

Répondre

4

Avez-vous une table avec toutes les dates? Si ce n'est pas le cas, vous pouvez envisager d'implémenter une table de calendrier et quitter la jointure de vos données sur la table de calendrier.

38

Vous pouvez utiliser un concept fréquemment appelé «tables de calendrier». Here est un bon guide sur la façon de créer des tables de calendrier dans MySql:

-- create some infrastructure 
CREATE TABLE ints (i INTEGER); 
INSERT INTO ints VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); 

-- only works for 100 days, add more ints joins for more 
SELECT cal.date, tbl.data 
FROM (
    SELECT '2009-06-25' + INTERVAL a.i * 10 + b.i DAY as date 
    FROM ints a JOIN ints b 
    ORDER BY a.i * 10 + b.i 
) cal LEFT JOIN tbl ON cal.date = tbl.date 
WHERE cal.date BETWEEN '2009-06-25' AND '2009-07-01'; 

Vous pouvez créer la table cal au lieu de la sous-sélection.

+0

Josef: Je pense que vous vouliez dire http://www.artfulsoftware.com/infotree/queries.php?&bw=1504#95 – feihtthief

+4

les urls sont exactement les mêmes, non? –

12
Select * from emp where joindate between date1 and date2; 

Mais cette requête n'affiche pas les données correctes.

Par exemple,

1-jan-2013 to 12-jan-2013. 

Mais ses données montrent

1-jan-2013 to 11-jan-2013. 
+2

J'ai utilisé ceci et c'était précis parce que mes champs de date sont du type DATETIME, donc en mettant dans les valeurs (pour les données dans un jour) comme ceci: 'BETWEEN '2013-10-12 00:00:00' et '2013-10 -12 23: 59: 59'' travaillé! Merci Monsieur. – arrayown

+1

@gulab, Vous pouvez utiliser 'SELECT * FROM emp WHERE DATE (joindate) ENTRE date1 ET date2;' – shweta

10

très facile à gérer cette situation

Vous pouvez utiliser ENTRE CLAUSE en combinaison avec DATE_SUB (maintenant() , INTERVALLE 30 JOURS) ET MAINTENANT()

SELECT 
    sc_cust_design.design_id as id, 
    sc_cust_design.main_image, 
    FROM 
    sc_cust_design 
WHERE 
    sc_cust_design.publish = 1 
    AND **`datein`BETWEEN date_sub(now() , INTERVAL 30 DAY) AND NOW()** 

Bonne programmation :)

1

SI vous pouvez l'éviter .. NE LE FAITES PAS

Les bases de données ne sont pas vraiment conçus pour cela, vous tentent effectivement de créer des données (quoique une liste de dates) dans une requête.

Pour toute personne disposant d'une couche d'application au-dessus de la requête DB, la solution la plus simple consiste à y remplir les données vides.

Vous aurez plus que probablement une boucle à travers les résultats de la requête de toute façon et peut mettre en œuvre quelque chose comme ceci:

loop_date = start_date 

while (loop_date <= end_date){ 

    if(loop_date in db_data) { 
    output db_data for loop_date 
    } 
    else { 
    output default_data for loop_date 
    } 

    loop_date = loop_date + 1 day 
} 

Les avantages sont réduits transmission de données; des requêtes plus simples et plus faciles à déboguer; et ne vous inquiétez pas de trop déborder la table du calendrier.

1

vous devez ajouter 1 jour à la date de fin, en utilisant: DATE_ADD('$end_date', INTERVAL 1 DAY)