将组分成单个记录的有效方法

时间:2010-09-16 16:42:45

标签: sql mysql group-by

我按照时间的推移对一些记录进行分组。我现在做的是什么(unixtime中的时间戳),

首先我做一个子选择来抓取我感兴趣的记录,

(SELECT timestamp AS target_time FROM table WHERE something = cool) AS subselect

然后我想查看那些与时间接近的记录,

SELECT id FROM table, subselect WHERE ABS(target_time - timestamp) < 1800 

但这是我遇到问题的地方。我想只想要target_time周围的记录之间的时间差异为&gt;的记录。 20分钟为此,我将target_time分组并添加HAVING部分。

SELECT id FROM table, first WHERE ABS(target_time - timestamp) < 3600 
GROUP BY target_time HAVING MAX(timestamp) - MIN(timestamp) > 1200

这很棒,我不喜欢的所有记录都已消失,但现在我只有该组的第一个id,当我真的想要所有ids时。我可以使用GROUP_CONCAT,但这让我变得一团糟,我不能再进行查询了。我真的希望从所有创建的组中返回所有ids。我还需要另一个SELECT声明吗?或者是否有更好的方法来构建我得到的东西?

谢谢,

SQL nub。

2 个答案:

答案 0 :(得分:1)

看看我的问题是否正确:

对于表中的给定行,如果这些记录的时间戳范围大于20分钟,则您希望知道类似记录的行集。您希望对表中的所有ID进行此操作。

如果您只是想要一个符合此标准的ID列表,那么它非常简单:

给出如下表格:

create table foo (id bigint(4), section VARCHAR(2), modification datetime);

你可以这样做:

select id, foo.section, min_max.min_modification, min_max.max_modification, abs(min_max.min_modification  - min_max.max_modification) as diff
from foo,
(select section, max(modification) max_modification, min(modification) min_modification from foo as inner_foo group by section) as min_max
where foo.section = min_max.section
and abs(min_max.min_modification  - min_max.max_modification) > 1800;

您正在根据“类似行”标准(在本例中为列部分)进行子选择,以获取该部分的最小和最大时间戳。此min和max适用于该部分中的所有ID。因此,对于“A”部分,您将有一个ID列表,对于“B”部分也是如此。

答案 1 :(得分:0)

我的假设是你想要一个看起来像的输出:

   id1, timestamp1, fieldA, fieldB
   id1, timestamp2, fieldA, fieldB
   id2, timestamp3, fieldA, fieldB
   id2, timestamp4, fieldA, fieldB
   id3, timestamp5, fieldA, fieldB
   id3, timestamp6, fieldA, fieldB

但这些记录的时间戳是在“target_time”的1200和1800秒之间,其中某些东西=酷?

   SELECT data.id, data.timestamp, data.fieldA, data.fieldB, ..., data.fieldX
     FROM events 
     JOIN data 
    WHERE events.something = cool_event    -- Gives the 'target_time' of cool_event
      AND ABS(event.timestamp - data.timestamp) BETWEEN 1200 and 1800   -- gives data records 'near' target time, but at least 20 minutes away.

如果'data'和'events'表是SAME表,那么只需使用表别名,但您可以将表连接到自身,也就是'SELF-JOIN'。

   SELECT data.id, data.timestamp, data.fieldA, data.fieldB, ..., data.fieldX
     FROM events AS target,  events AS data
    WHERE target.something = cool_event    -- gives the 'target_time' of cool_event
      AND ABS(target.timestamp - data.timestamp) BETWEEN 1200 and 1800   -- gives data records 'near' target time, but at least 20 minutes away.

这听起来很正确,并且不需要任何分组或聚合。

如有必要,您可以订购结果数据。

- J Jorgenson -