mysql - 识别 SQL 中的模式。是否可以?

标签 mysql sql oracle

我正在尝试复制下面的示例输出表,但不确定如何继续。我曾尝试使用 LAG 函数,但收效有限

CASE WHEN LAG(mode, 1) OVER(PARTITION BY Cluster_Name, Node_Name) ORDER BY 日期 != 模式 然后日期

它找到模式切换的日期,但我不确定如何复制示例输出表

一个循环在记录第一个气体模式/体积时开始,在记录最后一个水体积时结束。即:对于 Foxtrot,即使在 3/18/2019 有水值,也只发生 1 个循环。这是因为在此之前没有发生气体循环。

原始数据

| Cluster_Name | Node_Name | Mode  | volume | date      | *Annotation Only*|
|--------------|-----------|-------|--------|-----------|------------------|         
| Cluster A    | Foxtrot   | water | 100    | 3/18/2019 |                            
| Cluster A    | Foxtrot   | gas   | 200    | 3/19/2019 | Cycle 1                    
| Cluster A    | Foxtrot   | gas   | 200    | 3/20/2019 |                            
| Cluster A    | Foxtrot   | water | 100    | 3/21/2019 |                            
| Cluster B    | Alpha     | water | 820    | 4/29/2018 |                            
| Cluster B    | Alpha     | gas   | 500    | 4/30/2018 | Cycle 1                    
| Cluster B    | Alpha     | gas   | 500    | 5/1/2018  |                            
| Cluster B    | Alpha     | gas   | 500    | 5/2/2018  |                            
| Cluster B    | Alpha     | water | 1,000  | 5/3/2018  |                            
| Cluster B    | Alpha     | water | 1,000  | 5/4/2018  |                            
| Cluster B    | Alpha     | water | 1,000  | 5/5/2018  |                            
| Cluster B    | Alpha     | gas   | 300    | 5/6/2018  | Cycle 2                    
| Cluster B    | Alpha     | gas   | 300    | 5/7/2018  |                            
| Cluster B    | Alpha     | water | 2,000  | 5/8/2018  |                            
| Cluster B    | Alpha     | gas   | 300    | 5/9/2018  | Cycle 3                    
| Cluster B    | Alpha     | water | 2,000  | 5/10/2018 |                            
| Cluster B    | Alpha     | gas   | 1,500  | 5/11/2018 | Cycle 4                    

示例输出表

此表充当一种数据透视表,通过体积总和在集群/节点/周期上聚合。

| Cluster_Name | Node_Name | Mode  | Total_Volume | Cycle # |
|--------------|-----------|-------|--------------|---------|
| Cluster A    | Foxtrot   | gas   | 400          | Cycle 1 |
| Cluster A    | Foxtrot   | water | 100          | Cycle 1 |
| Cluster B    | Alpha     | gas   | 1,500        | Cycle 1 |
| Cluster B    | Alpha     | water | 3,000        | Cycle 1 |
| Cluster B    | Alpha     | gas   | 600          | Cycle 2 |
| Cluster B    | Alpha     | water | 2,000        | Cycle 2 |
| Cluster B    | Alpha     | gas   | 300          | Cycle 3 |
| Cluster B    | Alpha     | water | 1,200        | Cycle 3 |
| Cluster B    | Alpha     | gas   | 1,500        | Cycle 4 |

最佳答案

假设您使用的是 Oracle 或 MySQL 8 *(假设是因为您说您正在尝试使用 LAG(),而旧版本的 MySQL 没有 滞后())

还假设只有两种模式,并且您永远不需要第一种模式的任何读数。

WITH
    sorted_data AS
(
    SELECT
        rawdata.*,
        ROW_NUMBER() OVER (PARTITION BY cluster_name, node_name
                               ORDER BY date
                          )
                             AS node_seq_num,
        ROW_NUMBER() OVER (PARTITION BY cluster_name, node_name, mode
                               ORDER BY date
                          )
                             AS node_mode_seq_num
    FROM
        your_data
),
   aggregated_data AS
(
    SELECT
        cluster_name,
        node_name,
        mode,
        MIN(date)   AS first_date,
        MAX(date)   AS final_date,
        SUM(volume) AS total_volume,
        ROW_NUMBER() OVER (PARTITION BY cluster_name, node_name, mode, node_seq_num - node_mode_seq_num
                               ORDER BY node_seq_num - node_mode_seq_num
                          )
                             AS node_mode_group_seq_num
    FROM
        sorted_data
    GROUP BY
        cluster_name,
        node_name,
        mode,
        node_seq_num - node_mode_seq_num
)
SELECT
    *,
   node_mode_group_seq_num / 2   AS cycle_num
FROM
    aggregated_data
WHERE
    node_mode_group_seq_num > 1
ORDER BY
    cluster_name,
    node_name,
    mode,
    node_mode_group_seq_num

(在 MySQL 中,您需要 TRUNC(node_mode_group_seq_num/2))

关于mysql - 识别 SQL 中的模式。是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55283344/

相关文章:

php - 用于搜索邮政编码的文件或数据库?

php - 如何在 Yii 中使用 union 2 select 创建查询?

mysql - 使用 MySQL 在创建的 VIEW 中看不到 NULL 值

mysql - 数据库中存储重复数据的正确方法

mysql - 使用日历表在日期范围内插入值

android - 用户 ID 在登录系统的 Activity 之间共享

mysql - 向查询的最后一列添加注释但不在数据库中更新它

sql - SQL选择;连接字符串,避免在列为空的情况下使用双逗号?

sql - 在SQL(Oracle)中将datetime字段转换为仅一个日期字段

oracle - 在oracle 11G中自动删除最旧的分区