SQL-重置窗口计数

时间:2018-10-18 13:20:10

标签: sql function count sap hana

我正在使用sql并尝试获得以下结果(running_count)。

我确实尝试了窗口函数计数,但是我不知道如何实现计数器的重置。

select *,
     count(1) over 
(partition by ID, DATE order by DATE rows unbounded preceding) -1 as "run_count"  from table

我的(结果表)应如下所示。计数应在两天之间重置,但也应在A之间出现B时。

ID Date   Flag Running_Count
1  10/10   A   1 
**2  10/10   B   0** -> reset
**3  10/10   B   0** -> reset
4  10/10   A   1
5  10/10   A   2
6  10/10   A   3

1  11/10   B   0
2  11/10   B   0
3  11/10   A   1
4  11/10   A   2
5  11/10   A   3
6  11/10   A   4
**7  11/10   B   0** -> reset
8  11/10   A   1

3 个答案:

答案 0 :(得分:1)

您似乎想从每一天开始计算由“ B”分隔的“ A”。

如果是这样,您可以将组定义为每个值之前的“ B”数,然后进行一些计算:

select t.*,
       (case when flag = 'A' then row_number() over (partition by date, grp, flag order by id)
             else 0
        end) as running_count
from (select t.*, sum(case when flag = 'B' then 1 else 0 end) over (partition by date order by id) as grp
      from t
     ) t;

Here是一个学期(使用Postgres)。

答案 1 :(得分:0)

请您尝试遵循SQLScript select语句

有可能更容易解决。我使用了子选择来逐步显示解决方案。

最里面的SELECT使用SQL Lag() function检查从另一个值到'A'的变化

以下SubSelect使用SUM()聚合函数和无限制的先前选项来执行SQL running-sum解决方案

最外面的SELECT使用Row_Number()函数创建所需的计数值。

select
    id,
    date,
    flag,
    case when flag = 'A' then
    row_number() over (partition by date, groupid order by id) 
    else 0
    end as rn
from (
    select
        id,
        date,
        flag,
        sum(is_change) over (partition by date order by id rows unbounded preceding) groupid -- running sum
    from (
        select
            id,
            date,
            flag,
            case 
                when 
                    flag = 'A' and 
                    (
                        (lag(flag, 1) over (partition by date order by id)) is null or
                        (lag(flag, 1) over (partition by date order by id)) = 'B'
                    ) -- check prev
                then 1
                else 0
            end as is_change
        from TblTest
    ) tbl
) t
order by date, id

我希望它有用并且可以在您的开发中使用

enter image description here

答案 2 :(得分:0)

您可以根据B标志出现的次数来定义分组,然后使用Row_number为每个组的行编号:

SELECT
    ID,
    date,
    flag,
    CASE WHEN flag = 'B' THEN 0 ELSE ROW_NUMBER() OVER (PARTITION BY date, B_COUNT ORDER BY ID) END AS "RUNNING_COUNT"
FROM
    (
        SELECT
            TA.ID,
            TA.date,
            TA.flag,
            CASE WHEN SUM(TB.COUNT) IS NULL AND flag = 'A' THEN 0 ELSE SUM(TB.COUNT) END AS B_COUNT
        FROM
            table TA
            LEFT JOIN 
                        (
                            SELECT
                                ID, date, 1 AS "COUNT"
                            FROM
                                table
                            WHERE 
                                flag = 'B'                  
                        )   TB ON TA.date = TB.date AND TA.ID > TB.ID AND TA.flag = 'A'
        GROUP BY
            TA.ID,
            TA.date,
            TA.flag
    )
ORDER BY 
    date, ID, flag;

它将给您预期的结果。