SELECT 语句,带有附加逻辑,用于修改某些记录

Posted

技术标签:

【中文标题】SELECT 语句,带有附加逻辑,用于修改某些记录【英文标题】:SELECT Statement, with additional logic, in order to modify certain records 【发布时间】:2021-01-19 15:30:52 【问题描述】:

如何制定也可以修改Query 结果的SELECT 语句。

我有下表:

ID    Startdate     Enddate        Category

0,  "2021-05-05", "2021-05-20", "First Category" 
1,  "2021-05-06", "2021-05-10", "First Category"
2,  "2021-05-07", "2021-05-10", "First Category"
3,  "2021-05-08", "2021-05-15", "First Category"
4,  "2021-05-20", "2021-05-22", "Second Category"
5,  "2021-05-21", "2021-05-24", "Second Category"
6,  "2021-05-23", "2021-05-24", "First Category"

获取所有这些记录的 SQL 语句非常基本,但是我需要属于一个类别序列(0-3、4-5、6)的所有记录,Startdate 中的所有记录序列,必须设置为序列第一条记录的Startdate

因此,预期结果如下:

ID    Startdate     Enddate        Category

0,  "2021-05-05", "2021-05-20", "First Category" 
1,  "2021-05-05", "2021-05-10", "First Category"  //changed Startdate
2,  "2021-05-05", "2021-05-10", "First Category"  //changed Startdate
3,  "2021-05-05", "2021-05-15", "First Category"  //changed Startdate
4,  "2021-05-20", "2021-05-22", "Second Category"
5,  "2021-05-20", "2021-05-24", "Second Category" //changed Startdate
6,  "2021-05-23", "2021-05-24", "First Category"

【问题讨论】:

【参考方案1】:

这是一种间隙和孤岛问题,但您不想减少行数,只是为了存储信息。我建议运行max() 来确定“岛”的开始位置,累积总和来计算每行所在的“岛”。最后是您想要的窗口函数:

select t.*,
       min(startdate) over (partition by category, grp) as group_startdate
from (select t.*,
             sum(case when prev_enddate >= startdate then 0 else 1 end) over (partition by category order by startdate) as grp
      from (select t.*,
                   max(enddate) over (partition by category order by startdate rows between unbounded preceding and 1 preceding) as prev_enddate
            from t
           ) t
     ) t;

Here 是一个 dbfiddle。

【讨论】:

以上是关于SELECT 语句,带有附加逻辑,用于修改某些记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 select 语句和序列创建视图

带有 INSERT 语句的 INSERT 触发器

SQL SELECT INTO 语句

PostgreSQL 调用函数返回带有表和附加列的记录集

带有数字通配符的 UCanAccess Select 语句给出了意外的令牌:需要 REGEXP_MATCHES

《SQL 基础教程》第二章:查询基础