如何在字段值的每个给定增量上进行GROUP BY?

时间:2009-05-13 18:10:20

标签: python sql sqlite iteration increment

我有一个Python应用程序。它有一个SQLite数据库,其中包含Web Web scraper从Web检索到的有关事件的数据。此数据包括时间日期组,作为Unix时间戳,在为它们保留的列中。我想检索做事情的组织的名字,并计算他们做这些事情的频率,但是为了每周(即604,800秒)这样做,我有数据。

伪代码:

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

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

如果可能的话,我想避免从数据库中提取所有行并在Python中处理它们,因为这看起来效率低,而且b)可能没有意义,因为数据在数据库中。

3 个答案:

答案 0 :(得分: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年,这仍然是一个小表。

答案 1 :(得分:1)

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

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中的等效代码。

答案 2 :(得分: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更易于使用。