1

我有一个 Python 应用程序。它有一个 SQLite 数据库,里面充满了关于发生的事情的数据,由网络爬虫从网络上检索。该数据在为它们保留的列中包括时间-日期组,作为 Unix 时间戳。我想检索做某事的组织的名称并计算他们做这些事情的频率,但要每周(即 604,800 秒)执行此操作,我有数据。

伪代码:

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

本质上,我要做的是像在时间列上排序的列表一样遍历数据库,步长值为 604800。目的是分析总体中不同组织的分布如何随时间变化。

如果可能的话,我想避免从数据库中提取所有行并在 Python 中处理它们,因为这似乎 a)效率低下,并且 b)考虑到数据在数据库中,这可能毫无意义。

4

3 回答 3

1

创建一个表,列出自纪元以来的所有周,并将JOIN其添加到您的事件表中。

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;

每年只有 52-53 周。即使您将 Weeks 表填充 100 年,它仍然是一张小表。

于 2009-05-13T18:30:03.080 回答
1

要以基于集合的方式(这是 SQL 擅长的方式)执行此操作,您将需要基于集合的时间增量表示。这可以是临时表、永久表或派生表(即子查询)。我对 SQLite 不太熟悉,自从我使用 UNIX 以来已经有一段时间了。UNIX 中的时间戳距离某个设置的日期/时间仅 # 秒?使用标准日历表(在数据库中很有用)...

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

Calendar 表可以采用您想要的任何形式,因此您可以在其中使用 UNIX 时间戳作为 start_time 和 end_time。您只需使用您可能想要使用的任何可能范围内的所有日期预先填充它。即使从 1900-01-01 到 9999-12-31 也不会是一张非常大的桌子。对于许多报告类型的查询,它可以派上用场。

最后,此代码是 T-SQL,因此您可能需要将 DATEPART 和 DATEADD 转换为 SQLite 中的任何等效项。

于 2009-05-13T18:36:16.407 回答
1

不熟悉 SQLite 我认为这种方法应该适用于大多数数据库,因为它会找到周数并减去偏移量

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

在 Oracle 中,如果时间是日期列,我将使用以下内容:

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

SQLite 可能具有类似的功能,允许这种看起来更容易的 SELECT。

于 2009-05-13T20:14:00.163 回答