Frage

Ich habe eine Python-Anwendung. Es hat eine SQLite-Datenbank, voll von Daten über Dinge, die, abgerufen von einem Web-Schaber aus dem Web passieren. Diese Daten umfassen Zeit-date Gruppen, wie Unix-Zeitstempel, in einer Spalte für sie reserviert. Ich möchte die Namen von Organisationen abzurufen, die Dinge taten und zählen, wie oft sie sie taten, aber dies für jede Woche zu tun (das heißt 604.800 Sekunden) Ich habe Daten für.

Pseudocode:

for each 604800-second increment in time:
 select count(time), org from table group by org

Im Wesentlichen ist zu tun, was ich versuche, wie eine Liste auf der Zeitspalte, mit einem Schrittwert von 604800. Das Ziel sortierte durch die Datenbank laufen ist zu analysieren, wie die Verteilung der verschiedenen Organisationen in den gesamten im Laufe der Zeit verändert.

Wenn möglich, möchte ich alle Zeilen aus der DB zu vermeiden, ziehen und deren Verarbeitung in Python, da dies scheint a) ineffizient und b) wahrscheinlich sinnlos gegeben, dass die Daten in einer Datenbank ist.

War es hilfreich?

Lösung

Nicht mit SQLite vertraut zu sein denke ich, dieser Ansatz sollte für die meisten Datenbanken arbeiten, da sie die Wochennummer findet und subtrahiert den Offset

SELECT org, ROUND(time/604800) - week_offset, COUNT(*)
FROM table
GROUP BY org, ROUND(time/604800) - week_offset

In Oracle würde ich folgende verwenden, wenn Zeit eine Datumsspalte ist:

SELECT org, TO_CHAR(time, 'YYYY-IW'), COUNT(*)
FROM table
GROUP BY org, TO_CHAR(time, 'YYYY-IW')

SQLite hat wahrscheinlich eine ähnliche Funktionalität, die diese Art von SELECT ermöglicht, die einfacher auf dem Auge ist.

Andere Tipps

Erstellen Sie eine Tabelle, alle Wochen seit Beginn der Epoche und JOIN es der Ereignisse auf den Tisch.

CREATE TABLE Weeks (
  week INTEGER PRIMARY KEY
);

INSERT INTO Weeks (week) VALUES (200919); -- e.g. this week

SELECT w.week, e.org, COUNT(*)
FROM Events e JOIN Weeks w ON (w.week = strftime('%Y%W', e.time))
GROUP BY w.week, e.org;

Es gibt nur 52-53 Wochen pro Jahr. Selbst wenn Sie die Wochen-Tabelle für 100 Jahre füllen, das ist immer noch ein kleiner Tisch.

Um dies zu tun, in einem Satz basiert (was SQL ist gut) Sie eine Set-basierte Darstellung Ihrer Zeitschritte benötigen. Das kann eine temporäre Tabelle, eine permanente Tabelle oder einer abgeleiteten Tabelle (d.h. Unterabfrage) sein. Ich bin nicht allzu vertraut mit SQLite und es ist schon eine Weile her, seit ich mit UNIX gearbeitet habe. Zeitstempel in UNIX sind nur # Sekunden seit einiger eingestellte Datum / Zeit? Mit einer Standard-Kalender-Tabelle (was nützlich ist, in einer Datenbank zu haben) ...

SELECT
     C1.start_time,
     C2.end_time,
     T.org,
     COUNT(time)
FROM
     Calendar C1
INNER JOIN Calendar C2 ON
     C2.start_time = DATEADD(dy, 6, C1.start_time)
INNER JOIN My_Table T ON
     T.time BETWEEN C1.start_time AND C2.end_time  -- You'll need to convert to timestamp here
WHERE
     DATEPART(dw, C1.start_time) = 1 AND    -- Basically, only get dates that are a Sunday or whatever other day starts your intervals
     C1.start_time BETWEEN @start_range_date AND @end_range_date  -- Period for which you're running the report
GROUP BY
     C1.start_time,
     C2.end_time,
     T.org

Die Kalender-Tabelle kann nehmen, was Form Sie wollen, so dass Sie UNIX-Zeitstempel in der es für die Startzeit und end_time nutzen könnten. Sie haben soeben vorge füllen Sie es mit all den Terminen in jedem denkbaren Bereich, den Sie verwenden möchten. geht sogar von 1900-01-01 bis 9999-12-31 wird eine schrecklich große Tabelle nicht sein. Es kann für viele nützlich sein, vom Typ Abfrage berichten.

Schließlich ist dieser Code T-SQL, so werden Sie wahrscheinlich den Datepart und DATEADD konvertieren müssen, was auch immer die äquivalent ist in SQLite.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top