2016-11-27 2 views
4

Ich habe folgende Tabelle dargestellt:mysql select date Tag für Tag

     login 
      date      user  
     2016-11-23     1 
     2016-11-23     2 
     2016-11-23     3 
     2016-11-25     2 
     2016-11-25     5 
     2016-11-27     1 

aus obiger Tabelle, was ich diese bekommen will, ist wie:

 date     count(*) 
    2016-11-21     0 
    2016-11-22     0  
    2016-11-23     3 
    2016-11-24     0 
    2016-11-25     2 
    2016-11-26     0 
    2016-11-27     1 

Aber, weil es nur geht 2016-11-23 ist und 2016-11-25 und 2016-11-27, wenn ich so abfragen:

select date, count(*) 
from login 
where date between (current_date()-interval 7 day) and current_date() 
group by date 
order by date asc 

Es c Ich bekomme kein Ergebnis wie das, was ich wirklich bekommen möchte. Ist das Ergebnis von meiner login Tabelle möglich?

Antwort

3

Eine Möglichkeit ist, alle Tage vor erzeugen

select GenDate, count(Date) 
from login 
right join 
(select a.GenDate 
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as GenDate 
    from (select 0 as a 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) as a 
    cross join (select 0 as a 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) as b 
    cross join (select 0 as a 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) as c 
) a 
where a.GenDate between (current_date()-interval 7 day) and current_date())x 
ON x.GenDate=login.Date 
group by GenDate 
order by GenDate asc 
+1

Eigentlich ist 'COUNT (*)' hier nicht gut, es wird 1 Tage ohne Treffer zurückgeben. – sagi

+0

@sagi Korrigiert, Sie haben Recht – Mihai

1

eine abgeleitete Tabelle mit den gesuchten Daten zu verwenden:

SELECT t.date, count(s.date) 
FROM (SELECT '2016-11-21' as `date` UNION ALL 
     SELECT '2016-11-22' as `date` UNION ALL 
     ...) t 
LEFT JOIN login s 
ON(t.date = s.date) 
WHERE 
    t.date between (current_date()-interval 7 day) and current_date() 
GROUP BY t.date 
ORDER BY t.date 
1

Dies ist ein sehr gut bekannte Problem bei der Programmierung JOIN. Es gibt mehrere Lösungen.

  1. Gehen Sie über das Ergebnis mit PHP, und füllen Sie die fehlenden Tage im resultierenden Array.

  2. AS Sagi vorgeschlagen, erstellen Sie eine separate Tabelle, die alle Daten in dem Bereich von Tagen enthält, mit denen Ihre Anwendung arbeitet, dann können Sie diese Tabelle mit Ihrer Abfrage verknüpfen. Eines der Probleme ist, dass Sie von Zeit zu Zeit mehr Tage zu dieser Tabelle hinzufügen müssen, wenn Sie plötzlich Tage in der Zukunft oder in der Vergangenheit haben.