SQL Groupby表示已排序时间序列中的值

时间:2017-07-31 21:12:42

标签: sql postgresql

这是我想要实现的一个例子:

表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 |

只有type序列为createdAt时,SQL语句才应合并type。如果序列中类似new_message值的数量大于1,则new_message为其他messagecreatedAt相同(此if-else子句不是最重要的特征,一个只给出计数的陈述也很好。

谢谢。

更新

是否可以在时间序列中添加另一个因子,仅当最低和最高| 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 | 之间的差异为X时才分组。

e.g。如果我选择X = 24小时,表A的输出将变为:

JOIN

如果没有or,还有办法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用ROW_NUMBER s的差异:

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

答案 1 :(得分:1)

我会使用行号的差异然后使用单个子查询进行聚合:

function longestSubString(arr) {
    let globalSum = 0;
    let set = new Set();
    for (let i=0; i<arr.length; i++) {
        let current = arr[i];
        if (set.has(current)) {
            while (true) {
                let removeChar = arr[i - set.count];
                if (removeChar != current)
                    set.remove(removeChar);
                else
                    break;
            }
        } else {
            set.add(current);
            if (set.count > globalSum)
                globalSum = set.count;
        }
    }
    return globalSum;
}