2017-07-31 96 views
0

这里价值观是什么,我想实现一个例子:SQL GROUPBY在排序时间序列

表A:

| type | message |   createdAt   | 
|:----------:|:---------:|:--------------------------:| 
| create  | awesome | 2017-07-21 11:20:35.147629 |  
| create  | hello | 2017-07-21 11:20:35.147629 |  
| create  | good  | 2017-07-22 10:20:34.123331 |  
| upload  | nope  | 2017-07-22 11:28:08.815828 |  
| create  | test  | 2017-07-22 11:29:35.147629 |  
| create  | hello | 2017-07-22 12:20:35.147629 | 

所需的输出:

| type | new_message |  new_createdAt  | 
|:------:|:------------:|:--------------------------:| 
| create |  3  | 2017-07-22 10:20:34.123331 | 
| upload |  nope  | 2017-07-22 11:28:08.815828 | 
| create |  2  | 2017-07-22 12:20:35.147629 | 

的SQL语句如果它们的顺序为createdAt,则应该组合类似的type。如果一个序列中的相似值type的数量大于1,那么new_message是其他的new_messagemessage相同(这个if-else子句不是最重要的特征,只是给出count的语句也可以)。

谢谢。

UPDATE

是否有可能在时间序列中增加的另一个因素,分组只有在最低和最高createdAt之间的差别是说十

例如如果我选择X = 24个小时,输出表A将变更为:

| type | new_message |  new_createdAt  | 
|:------:|:------------:|:--------------------------:| 
| create |  2  | 2017-07-21 11:20:35.147629 | 
| create |  good  | 2017-07-22 10:20:34.123331 | 
| upload |  nope  | 2017-07-22 11:28:08.815828 | 
| create |  2  | 2017-07-22 12:20:35.147629 | 

有什么办法没有JOIN这样做。

+0

使用[this](https://gis.stackexchange)解决时间间隔问题(** UPDATE **部分)。 com/a/127874) –

回答

2

您可以使用ROW_NUMBER分野:

WITH CteRn AS(
    SELECT *, 
     ROW_NUMBER() OVER(ORDER BY createdAt) 
      - ROW_NUMBER() OVER(PARTITION BY type ORDER BY createdAt) AS rn 
    FROM Tbl 
) 
SELECT 
    type, 
    CASE 
     WHEN COUNT(*) > 1 THEN CAST(COUNT(*) AS VARCHAR(30)) 
     ELSE MAX(cte.message) 
    END AS message, 
    MAX(cte.createdAt) AS createdAt 
FROM CteRn cte 
GROUP BY cte.type, cte.rn 
ORDER BY MAX(cte.createdAt); 

ONLINE DEMO

+0

谢谢,多一点解释会有所帮助。 –

1

我会做到这一点使用行号,然后聚集的差异,用一个单一的子查询:

select type, 
     (case when count(*) = 1 then max(message) else count(*)::text end) as message, 
     min(created_at) as new_createdAt 
from (select t.*, 
      row_number() over (order by createdAt) as seqnum_c, 
      row_number() over (partition by type order by createdAt) as seqnum_tc 
     from t 
    ) t 
group by type, (seqnum_c - seqnum_tc) 
order by new_createdAt;