Postgresql 基于输入为两行之间的行添加开始和结束日期的SQL查询
我有一个名为Acount的表,其结构如下Postgresql 基于输入为两行之间的行添加开始和结束日期的SQL查询,postgresql,Postgresql,我有一个名为Acount的表,其结构如下 acc_id name value phase date 1 acc_type trial start t1 1 name1 value1 phase1 t2 1 acc_type trial end t3 1 name2 value2 phase2 t4
acc_id name value phase date
1 acc_type trial start t1
1 name1 value1 phase1 t2
1 acc_type trial end t3
1 name2 value2 phase2 t4
1 acc_type trial start t5
1 name3 value3 phase2 t6
1 name4 value4 phase4 t7
1 acc_type trial end t8
表是根据日期排序的
我想要的是添加两列start\u date
和end\u date
,并更新特定阶段值对的列start和end
,其中name
是acc\u type
和value
是trial
因此,输出将如下所示:
acc_id name value phase date start_date end_date
1 acc_type trial start t1 t1 t3
1 name1 value1 phase1 t2 t1 t3
1 acc_type trial end t3 t1 t3
1 name2 value2 phase2 t4
1 acc_type trial start t5 t5 t8
1 name3 value3 phase2 t6 t5 t8
1 name4 value4 phase4 t7 t5 t8
1 acc_type trial end t8 t5 t8
我正在使用PostgreSQL。这很复杂,因为需要按开始和结束进行分区。如果我假设正确的顺序是日期,那么您可以使用累积
max()
:
编辑:
我注意到“中间”有一些价值观。这需要更复杂的逻辑。其思想是计算开始和结束的净数量,并将其用于过滤:
select t.*,
(case when netstartend > 0 or phase in ('start', 'end')
then max(case when phase = 'start' then date end) over
(partition by acc_id order by date)
end) as start_date,
(case when netstartend > 0 or phase in ('start', 'end')
then max(case when phase = 'end' then date end) over
(partition by acc_id order by date)
end) as end_date
from (select t.*,
sum(case when phase = 'start' then 1 when phase = 'end' then -1 else 0 end) over
(order by date) as netstartend
from t
) t;
这很复杂,因为需要按开始和结束进行分区。如果我假设正确的顺序是日期,那么您可以使用累积
max()
:
编辑:
我注意到“中间”有一些价值观。这需要更复杂的逻辑。其思想是计算开始和结束的净数量,并将其用于过滤:
select t.*,
(case when netstartend > 0 or phase in ('start', 'end')
then max(case when phase = 'start' then date end) over
(partition by acc_id order by date)
end) as start_date,
(case when netstartend > 0 or phase in ('start', 'end')
then max(case when phase = 'end' then date end) over
(partition by acc_id order by date)
end) as end_date
from (select t.*,
sum(case when phase = 'start' then 1 when phase = 'end' then -1 else 0 end) over
(order by date) as netstartend
from t
) t;
你的acc_id相同吗?你的acc_id相同吗?结果并不像预期的那样。开始日期看起来不错,但结束日期没有按要求到来。谢谢您可以查看此链接“”我正在查看您编辑的答案。我会让你知道结果的。谢谢。以上评论是针对您的第一个解决方案。仍然没有达到预期的效果。开始日期很完美,但结束日期不正确。请你调查一下好吗。谢谢。@Rajeevkumar:您能为您遇到的问题提供一个解决方案吗?这总比让戈登做你所有的工作好。:-)@Gordon Linoff:这对我很有效。在结束日期的情况下,几乎不需要更改。我使用最小值代替最大值,并使用“按日期排序说明”。。然后它成功了。非常感谢您的查询。结果没有按预期出现。开始日期看起来不错,但结束日期没有按要求到来。谢谢您可以查看此链接“”我正在查看您编辑的答案。我会让你知道结果的。谢谢。以上评论是针对您的第一个解决方案。仍然没有达到预期的效果。开始日期很完美,但结束日期不正确。请你调查一下好吗。谢谢。@Rajeevkumar:您能为您遇到的问题提供一个解决方案吗?这总比让戈登做你所有的工作好。:-)@Gordon Linoff:这对我很有效。在结束日期的情况下,几乎不需要更改。我使用最小值代替最大值,并使用“按日期排序说明”。。然后它成功了。谢谢你的提问。