我有一张桌子

CREATE TABLE consumer_occurrence_restoration_times (
    consumer_id INT,
    start_time TIMESTAMP,
    end_time TIMESTAMP
);

数据在哪里

INSERT INTO consumer_occurrence_restoration_times (consumer_id, start_time, end_time)
VALUES
    (1, '2023-09-24 20:00:00', '2023-09-25 12:00:00'),
    (2, '2023-09-24 21:00:00', '2023-09-25 13:00:00'),
    (1, '2023-09-26 20:00:00', '2023-09-28 02:00:00'),
    (3, '2023-09-25 19:00:00', '2023-09-26 10:00:00'),
    (4, '2023-09-25 21:30:00', '2023-09-27 14:00:00'),
    (5, '2023-09-25 21:30:00', '2023-09-25 22:00:00')

我想将此数据插入到另一个表tbl_diburaction using a query中,以便它插入一天的数据,即,开始时间与结束时间发生在同一天,而不是在第二天的00:00:00小时之后.

CREATE TABLE tbl_bifurcation (
    consumer_id INT,
    start_time TIMESTAMP,
    end_time TIMESTAMP,
  isdaydiff INT
);

Consumer_ocurence_RESTORE_TIMES表具有如下数据:

consumer_id   start_time            end_time
1             2023-09-24 20:00:00   2023-09-25 00:00:00
2             2023-09-24 21:00:00   2023-09-25 13:00:00
1             2023-09-26 20:00:00   2023-09-28 02:00:00
3             2023-09-25 19:00:00   2023-09-26 10:00:00
5             2023-09-25 21:30:00   2023-09-25 22:00:00

INSERT查询将来自Consumer_ocurence_Restore_Times表的数据插入到另一个名为tbl_diburtion的表中.但是,考虑从START_TIME到END_TIME的一天,它需要将时间间隔拆分成单独的日期,并将它们作为单独的行插入. 此外,如果某些数据的开始时间为‘2023-09-26 20:00:00’,结束时间为‘2023-09-27 20:00:00’,则isday diff为1,但当结束时间为‘2023-09-27 00:00:00’时,isday diff仍为0. 例如,如果START_TIME为‘2023-09-26 20:00:00’,END_TIME为‘2023-09-28 02:00:00’,我希望在tbl_diburaction中插入如下行:

consumer_id start_time end_time isdaydiff
1 2023-09-24 20:00:00 2023-09-25 00:00:00 0
2 2023-09-24 21:00:00 2023-09-25 00:00:00 1
2 2023-09-25 00:00:00 2023-09-25 13:00:00 1
1 2023-09-26 20:00:00 2023-09-27 02:00:00 1
1 2023-09-27 02:00:00 2023-09-28 00:00:00 1
1 2023-09-28 00:00:00 2023-09-28 02:00:00 1
3 2023-09-25 19:00:00 2023-09-26 00:00:00 1
3 2023-09-26 00:00:00 2023-09-26 10:00:00 1
5 2023-09-25 21:30:00 2023-09-25 22:00:00 0

这里,当分支完成时,isday sdiff=1(在除第一行和最后一行之外的所有行中),而不是在所有情况下.

Condition for updating isdaydiff

Isday diff=0仅用于开始日期和结束日期的Forking ,并且仅当开始日期和结束日期不在同一天时才进行Forking .它与Consumer_id无关.无论任何数据,每一行都是单独的行,与前一行没有任何问题.但是,只有当下一行中的Start_Date大于或等于具有相同Consumer_id的前一行end_date时,同一使用者才会有不同的行.

bifuracted_query添加了小提琴链接

推荐答案

您可以首先插入不需要拆分的记录,然后使用需要拆分的选项插入UNION ALL记录.使用generate_series()生成中间的天数.Demo:

INSERT INTO tbl_bifurcation
SELECT *, 0 as isdaydiff
FROM consumer_occurrence_restoration_times
WHERE start_time::date=end_time::date     --the ones
OR (  end_time::date=(start_time::date+1) --that don't require
    AND end_time::time='00:00:00'::time)  --splitting
UNION ALL  
SELECT consumer_id,
  added_date+case when added_date::date=start_time::date 
                  then start_time::time::interval 
                  else '0s'::interval end,
  added_date+case when added_date::date=end_time::date 
                  then end_time::time::interval 
                  else '1 day'::interval end,
  1 as isdaydiff
FROM (
   SELECT *,generate_series(start_time::date,
                            end_time::date,
                            '1 day'::interval) added_date
   FROM consumer_occurrence_restoration_times
   WHERE start_time::date<>end_time::date       --opposite condition
   AND NOT (end_time::date=(start_time::date+1) --so the ones to split
            AND end_time::time='00:00:00'::time) ) a;

SELECT * FROM tbl_bifurcation
ORDER BY 1,2,3;
consumer_id start_time end_time isdaydiff
1 2023-09-24 20:00:00 2023-09-25 00:00:00 0
1 2023-09-26 20:00:00 2023-09-27 00:00:00 1
1 2023-09-27 00:00:00 2023-09-28 00:00:00 1
1 2023-09-28 00:00:00 2023-09-28 02:00:00 1
2 2023-09-24 21:00:00 2023-09-25 00:00:00 1
2 2023-09-25 00:00:00 2023-09-25 13:00:00 1
3 2023-09-25 19:00:00 2023-09-26 00:00:00 1
3 2023-09-26 00:00:00 2023-09-26 10:00:00 1
5 2023-09-25 21:30:00 2023-09-25 22:00:00 0
  1. +case有条件地恢复一系列时间戳的开始和结束的时间部分.介于两者之间的一切都将只在午夜使用.
  2. 您还可以使用extract()timestamp中获取日期、时间和更多信息.因为我只需要日期和时间,而且datetime都有自己的类型,预定义了向上和向下转换,所以我使用了这些.

Sql相关问答推荐

如何简化此表达以使搜索查询忽略标点符号?Microsoft Access 2007-2016

使用group by后我的平均输出不是我想要的

SUM(条件)在Oracle?

如何使用PostGIS从单个表中 Select 所有相交面组

如何在不更改S代码的情况下,判断存储过程调用了多少次clr函数?

如何根据给定条件PostgreSQL迭代减少组中的行数

根据是否出现过零来筛选数据(跨多行)

在UNION查询中查找MIN

将时间范围划分为全天和前后剩余小时

Netezza SQL:判断两个表是否相同

根据标识符将两行合并为一行

使用长 IN 子句的 SQL 优化

SQL:考虑合并分支计算分支的增长百分比

BigQuery导航函数计算ID

Postgres如何在一个日历周中前进和回填值

PostgreSQL - 递归地聚合来自不同列的属性

使用in和and运算符过滤记录的条件

编写查询以根据级别 (p2) 返回父位置

如何将 CONCATENATED 值与临时表中的值匹配

以 15 分钟为间隔的使用情况SQL 查询