2016-06-15 8 views
0

Ich bin mit SQL Server und ich habe die folgende Tabelle:SQL Server Zählung Nachricht pro Tag

tbl_Message: 
id, date, group_id 

die eine Tabelle Nachrichten enthalten ist: es ist id, das Datum es gesendet wurde, die Gruppe es gesendet wurde In. Ich versuche, die Anzahl der Nachrichten jeden Tag zu berechnen. Ich habe eine Abfrage dafür gemacht, aber es gibt keine Tage ohne Nachrichten zurück. Die Abfrage ist:

SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay, 
COUNT(*) AS countMsgDay 
FROM tbl_Message 
WHERE group_id = 1 
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) 

Beispiel:

Für tbl_Message

id |  date     | group_id 
---------------------------------------- 
1 | 2014-10-01 21:04:00.000 | 1 
2 | 2014-10-03 21:09:00.000 | 1 

die Abfrage:

dateDay     | countMsgDay 
--------------------------------- 
2014-10-01 00:00:00.000 | 1 
2014-10-03 00:00:00.000 | 1 

und was ich will, ist:

dateDay     | countMsgDay 
--------------------------------- 
2014-10-01 00:00:00.000 | 1 
2014-10-02 00:00:00.000 | 0 
2014-10-03 00:00:00.000 | 1 
+1

Sie werden einen Weg benötigen, um Daten für die fehlenden Tage zu generieren. Eine Option wäre eine Datumstabelle, die Sie Ihrem Schema hinzufügen könnten. –

Antwort

1

Verwenden Sie diesen Link, um Daten zwischen Ihren Daten zu generieren. Verwenden Sie start_date als min(dateDay) und end_date als max(dateDay)

How to list all dates between two dates

nun diese Tabelle verwenden und mit Ihrer Anfrage beizutreten. Sagen Tabelle zum Ableiten der Tabelle ist dateRange. So generiert select * from dateRange Datum von 2014-10-01 bis 2014-10-03.

nun eine Abfrage wie unten verwenden, um den gewünschten Ausgang

select dr.dateval,t.countMsgDay 
from dateRange dr 
left join 
(
    SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay, 
    COUNT(*) AS countMsgDay 
    FROM tbl_Message 
    WHERE group_id = 1 
    GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) 
) t 
on dr.dateval=t.dateDay 
1

Die normale Lösung für dieses Problem besteht darin, alle Tage von Daten zu generieren und dann eine left join zu verwenden. Sie können die Tage auf verschiedene Arten generieren:

  • Verwenden einer Kalendertabelle.
  • Verwendung rekursiver CTEs.
  • Verwenden einer Nummerentabelle.
  • Explizit einschließlich der Daten in der Abfrage.

In einigen Fällen gibt es eine einfachere Lösung, die bedingte Aggregation ist. Dies setzt voraus, dass für jeden Tag mindestens ein Datensatz vorhanden ist. Dann können Sie bedingte Aggregation für diesen Zweck verwenden:

SELECT CAST(date as DATE) as dateDay, 
     SUM(CASE WHEN group_id = 1 THEN 1 ELSE 0 END) as countMsgDay 
FROM tbl_Message 
GROUP BY CAST(date as DATE) 
ORDER BY dateDay; 

Dies wird für Sie arbeiten, vorausgesetzt, dass jeden Tag mindestens einen Datensatz in der Tabelle hat.

1

Sie benötigen einen Kalender Tisch zu bekommen, sobald Sie haben, dass alles, was Sie tun müssen, ist die Verwendung links mit dieser Tabelle kommt alle Daten zu erhalten .Es gibt viele use cases to calendar table andere als diese

EX:

select 
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay, 
COUNT(*) AS countMsgDay 
from 
Calendar c 
left join 
yourtable t 
on t.date=c.date 
and group_id = 1 
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) 
Verwandte Themen