2017-10-12 3 views
0

J'ai une base de données dans laquelle j'ai une table pour enregistrer des rapports. Chaque rapport a une date (année-mois-jour) qui est définie à chaque création du rapport. Après un grand nombre de tests, j'ai eu quelque chose à travailler, mais pas comme je voudrais que ça marche. Je veux obtenir la quantité de rapports qui ont été faits tous les mois entre une date initiale (année-mois-jour) et une date finale (année-mois-jour). Mais je ne suis pas sûr de savoir comment le faire.Obtenir un "compte" sur une base de données en utilisant "où" pour définir une limite à la date

Voici la phrase MySQL j'utilise en ce moment:

SELECT meses.month id_mes, count(re_fecha) total 
     FROM 
     (
       SELECT 1 AS MONTH 
        UNION SELECT 2 AS MONTH 
        UNION SELECT 3 AS MONTH 
        UNION SELECT 4 AS MONTH 
        UNION SELECT 5 AS MONTH 
        UNION SELECT 6 AS MONTH 
        UNION SELECT 7 AS MONTH 
        UNION SELECT 8 AS MONTH 
        UNION SELECT 9 AS MONTH 
        UNION SELECT 10 AS MONTH 
        UNION SELECT 11 AS MONTH 
        UNION SELECT 12 AS MONTH 

     ) as meses 

LEFT JOIN reportes ON month(re_fecha) = meses.MONTH 
WHERE re_fecha BETWEEN '2017-01-01' AND '2017-08-31' 
GROUP BY meses.MONTH, monthName(re_fecha) 

Ceci est le résultat suivant, je reçois avec la phrase MySQL:

id_mes | total 
--------------- 
    04 | 15 
    05 | 5 
    06 | 15 
    07 | 2 

I Je ne suis pas sûr si cela aide de quelque façon, mais si je n'utilise pas le "where re_fechas ..." j'obtiens un résultat qui est plus proche de ce que nous recherchons:

id_mes | total   
-------------   
01  | 0   
02  | 0   
03  | 0   
04  | 15    
05  | 5 
06  | 15 
07  | 2 
08  | 6 
09  | 0 
10  | 0 
11  | 0 
12  | 0 

Et enfin, ce que je voudrais voir:

id_mes  | total    
-------------------  
01-2017  | 0    
02-2017  | 0    
03-2017  | 0    
04-2017  | 15 
05-2017  | 5 
06-2017  | 15 
07-2017  | 2 
08-2017  | 6 

J'ai deux problèmes avec la façon dont il fonctionne maintenant:

  1. Quand j'utilise la phrase « où "les mois qui ont 0 rapports aux dates spécifiées, ne sont pas montrés. Si je n'utilise pas "où", je reçois les choses presque comme je le veux, mais pas dans la gamme de dates que je veux.

  2. L'autre problème que j'ai eu est que je voudrais obtenir l'année du mois (comme indiqué dans le bloc de code désiré ci-dessus).

J'espère que cela est assez d'informations pour tout comprendre, je ne sais pas si je pouvais fournir la base de données, mais si vous pensez que cela aiderait, faites le moi savoir.

Répondre

0

Vous l'avez presque compris.

Si vous ajoutez OR re_fecha IS NULL à votre clause WHERE, vous obtiendrez presque ce que vous vouliez.

je suis venu avec une autre solution qui peut vous aider:

SELECT meses.aMonth aMonth, COUNT(re_fecha) total 
FROM (
    -- Listing all months in period 
    SELECT DATE_FORMAT(m1, '%m-%Y') aMonth 
    FROM (
    -- Range limit: about 21 years 
    SELECT 
    ('2017-01-01' - INTERVAL DAYOFMONTH('2017-01-01')-1 DAY) +INTERVAL m MONTH as m1 
    FROM (
     SELECT @rownum:[email protected]+1 m FROM 
     (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t1, 
     (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t2, 
     (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t3, 
     (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t4, 
     (SELECT @rownum:=-1) t0) d1 
    ) d2 
    WHERE m1 <= '2017-08-31' 
    ORDER BY m1) meses 
LEFT JOIN reportes ON DATE_FORMAT(re_fecha, '%m-%Y') = meses.aMonth 
WHERE re_fecha BETWEEN '2017-01-01' AND '2017-08-31' 
OR re_fecha IS NULL 
GROUP BY meses.aMonth; 

Testez: http://sqlfiddle.com/#!9/d21de6/27

Exemple de sortie:

aMonth total 
01-2017 0 
02-2017 0 
03-2017 0 
04-2017 15 
05-2017 5 
06-2017 0 
07-2017 2 
08-2017 0 

Si vous utilisez MySQL n'a pas été, alors vous pourrait utiliser un FULL OUTER JOIN au lieu de LEFT JOIN.N'oubliez pas que cette solution est limitée à 21 ans. Essayez-le en changeant seulement la date initiale en 1970 et voyez-le par vous-même. Si nécessaire, ajoutez (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) tn, pour augmenter le nombre de mois.

Références et liens utiles:

MySQL monthly Sale of last 12 months including months with no Sale
How to get a list of months between two dates in mysql
How to do a FULL OUTER JOIN in MySQL?

+0

@Strawberry même si cela est laborieux, il est assez simple si OP ne pas besoin de plages variables de mois. Et bien que nous ayons besoin d'un 'FULL OUTER JOIN', nous ne l'avons pas sur MySQL, nous devons donc l'émuler avec un 'LEFT JOIN'. J'ai mis à jour ma réponse en ajoutant une autre façon d'aborder ce problème. – MiguelKVidal

+0

Gotcha - mon erreur. – Strawberry

+0

Cela fonctionne parfaitement! Nous l'avons essayé et l'avons déjà implémenté et il fonctionne comme nous le voulions. J'apprécie la réponse. Merci les gars. –

0

Dans votre requête, essayez de changer WHERE en AND.