我有一个 PostgreSQL 表,其中包含:person_identifier,period_identifier,status
using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}
我需要包括一个 person | period | status
-------+--------+--------
Bob | Jan | new
Bob | Feb | retained
Bob | Mar | retained
Bob | Apr | dormant
Bob | May | dormant
Bob | Jun | resurected
Bob | Jul | retained
Bob | Agu | dormant
Jim | Jan | new
Jim | Feb | dormant
Jim | Mar | dormant
Jim | Apr | dormant
Jim | May | dormant
Jim | Jun | resurected
Jim | Jul | dormant
Jim | Agu | resurected
分组的counter
,并限制状态变化时计数器必须重新启动为1。
我尝试了以下查询,但是每当状态更改时,计数器都不会person, status
降至1:
reset
这是我的查询与实际需要的区别; SELECT
*,
ROW_NUMBER() OVER (PARTITION BY person, status ORDER BY period) AS wrong_counter
FROM
my_table
:
* stands for wrong value
有人可以帮我吗?
答案 0 :(得分:0)
我做了一些归一化:
DateTime
并用作基表:public.tbl_test
然后我进行一些计算:首先获取实际行之前的行中的状态,是否为status_change。 创建一个help_partition,然后获取该help_partition上的row_number。
person -> person_fk,
period -> period_int, Jan = 1 ...
status -> status_fk
并得到:(最后一行是您需要的计数器)
with temp_base_data as
(
select
*,
lag(status_fk,1,-1) over(ORDER BY person_fk, period_int) as status_before,
case
when lag(status_fk,1,-1) over(ORDER BY person_fk, period_int) = status_fk and lag(person_fk ,1,-1) over(ORDER BY person_fk, period_int) = person_fk
then 0
else 1
end as status_change
from public.tbl_test
order by person_fk, period_int
),
temp_partition AS
(
select
*,
sum(status_change) over ( order by person_fk, period_int RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as help_partition
from temp_base_data
order by person_fk, period_int
)
select
* ,
row_number() over (PARTITION by help_partition order by person_fk, period_int) as counter
from temp_partition
order by id