SQL 当二进制列等于 0 时计数重置
SQL Count reset when binary column equals 0
下面有一个示例 table。我正在尝试创建一个计数,当 Flag
等于 0 时无需递归 table.
Animal Order Flag
Cat 1 0
Cat 2 0
Cat 3 1
cat 4 1
cat 5 0
cat 6 1
cat 7 1
Dog 1 0
Dog 2 1
Dog 3 1
Dog 4 1
Dog 5 0
Dog 6 0
Dog 7 1
我已经尝试了各种 row_number
、 rank
、 dense_rank
但没有一个能让我接近。我得到的最接近的是使用下面的滞后方法,但它只能计数到 2,并且需要能够无限计数。
延迟:
MAX(flag )
OVER(PARTITION BY 1 ORDER BY Order
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
期望的输出
Animal Order Flag Count
Cat 1 0 0
Cat 2 0 0
Cat 3 1 1
cat 4 1 2
cat 5 0 0
cat 6 1 1
cat 7 1 2
Dog 1 0 0
Dog 2 1 1
Dog 3 1 2
Dog 4 1 3
Dog 5 0 0
Dog 6 0 0
Dog 7 1 1
为每一行分配一个grouping
。然后使用 row_number()
:
select t.*,
(case when flag = 0 then 0
else row_number() over (partition by animal, grouping order by order) - 1
end) as count
from (select t.*,
sum(case when flag = 0 then 1 else 0 end) over
(partition by animal
order by order
rows between unbounded preceding and current row
) as grouping
from t
) t
- 1
是因为1
的每一个序列还包括前面的0
。您也可以将其表示为:
else row_number() over (partition by animal, grouping, flag order by order)
所以只有 1
人在组中。
您也可以使用 RESET WHEN
执行此操作,这是一个 Teradata 扩展:
SELECT animal, order, flag,
SUM(flag) OVER(
PARTITION BY animal -- Group by animals
ORDER BY order
RESET WHEN flag = 0 -- Reset count to 0
ROWS UNBOUNDED PRECEDING -- Cumulative count
) AS count
FROM mytable
我没有要测试的 TD 系统,但请尝试一下并告诉我。
下面有一个示例 table。我正在尝试创建一个计数,当 Flag
等于 0 时无需递归 table.
Animal Order Flag
Cat 1 0
Cat 2 0
Cat 3 1
cat 4 1
cat 5 0
cat 6 1
cat 7 1
Dog 1 0
Dog 2 1
Dog 3 1
Dog 4 1
Dog 5 0
Dog 6 0
Dog 7 1
我已经尝试了各种 row_number
、 rank
、 dense_rank
但没有一个能让我接近。我得到的最接近的是使用下面的滞后方法,但它只能计数到 2,并且需要能够无限计数。
延迟:
MAX(flag )
OVER(PARTITION BY 1 ORDER BY Order
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
期望的输出
Animal Order Flag Count
Cat 1 0 0
Cat 2 0 0
Cat 3 1 1
cat 4 1 2
cat 5 0 0
cat 6 1 1
cat 7 1 2
Dog 1 0 0
Dog 2 1 1
Dog 3 1 2
Dog 4 1 3
Dog 5 0 0
Dog 6 0 0
Dog 7 1 1
为每一行分配一个grouping
。然后使用 row_number()
:
select t.*,
(case when flag = 0 then 0
else row_number() over (partition by animal, grouping order by order) - 1
end) as count
from (select t.*,
sum(case when flag = 0 then 1 else 0 end) over
(partition by animal
order by order
rows between unbounded preceding and current row
) as grouping
from t
) t
- 1
是因为1
的每一个序列还包括前面的0
。您也可以将其表示为:
else row_number() over (partition by animal, grouping, flag order by order)
所以只有 1
人在组中。
您也可以使用 RESET WHEN
执行此操作,这是一个 Teradata 扩展:
SELECT animal, order, flag,
SUM(flag) OVER(
PARTITION BY animal -- Group by animals
ORDER BY order
RESET WHEN flag = 0 -- Reset count to 0
ROWS UNBOUNDED PRECEDING -- Cumulative count
) AS count
FROM mytable
我没有要测试的 TD 系统,但请尝试一下并告诉我。