【问题标题】:How to convert data from one row to multiple rows base on Date如何根据日期将数据从一行转换为多行
【发布时间】:2023-01-30 20:21:01
【问题描述】:

我希望根据 start_time 和 end_time 将数据从一行转换为多行。

输入数据:

ID Start_Time End_Time Down_Mins
ABC123 11/22/2022 12:01 11/29/2022 14:33 10232.47

我需要为这个需求写SQL:

输出数据:

ID Start_Time End_Time Down_Mins
ABC123 11/22/2022 12:01 11/23/2022 7:00 1138.55
ABC123 11/23/2022 7:00 11/24/2022 7:00 1440
ABC123 11/24/2022 7:00 11/25/2022 7:00 1440
ABC123 11/25/2022 7:00 11/26/2022 7:00 1440
ABC123 11/26/2022 7:00 11/27/2022 7:00 1440
ABC123 11/27/2022 7:00 11/28/2022 7:00 1440
ABC123 11/28/2022 7:00 11/29/2022 7:00 1440
ABC123 11/29/2022 7:00 11/29/2022 14:33 453.92

enter image description here

【问题讨论】:

  • 请不要垃圾邮件很多不必要的标签。 SQL Server 和 Oracle 是两个不同的 RDBMS,具有不同的语法。鉴于您的其他标签与 Oracle 相关,我删除了 SQL Server;如果不正确,请edit您的问题并添加正确的标签。
  • 您使用的是哪个数据库管理系统? (您已经得到了一个特定于产品的答案——希望您没有浪费别人的时间为“错误”的 dbms 写答案。)
  • Start_Time 和 End_Time 列的数据类型?
  • 感谢大家的支持,抱歉造成混淆,我正在使用它的 oracle 数据库。

标签: sql oracle


【解决方案1】:

您可以使用递归查询将数据拆分为从早上 7 点开始的每个 24 小时周期的行:

WITH days (id, start_time, day_end, end_time, day_mins, down_mins) AS (
  SELECT id,
         start_time,
         LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time),
         end_time,
         LEAST((LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time) - start_time) * 24 * 60, down_mins),
         down_mins - LEAST((LEAST(TRUNC(start_time - INTERVAL '7' HOUR) + INTERVAL '31' HOUR, end_time) - start_time) * 24 * 60, down_mins)
  FROM   table_name
UNION ALL
  SELECT id,
         day_end,
         LEAST(day_end + INTERVAL '24' HOUR, end_time),
         end_time,
         LEAST((LEAST(day_end + INTERVAL '24' HOUR, end_time) - day_end) * 24 * 60, down_mins),
         down_mins - LEAST((LEAST(day_end + INTERVAL '24' HOUR, end_time) - day_end) * 24 * 60, down_mins)
  FROM   days
  WHERE  day_end < end_time
  AND    down_mins > 0
)
SEARCH DEPTH FIRST BY id, start_time SET order_id
SELECT id,
       start_time,
       day_end AS end_time,
       day_mins AS down_mins
FROM   days;

其中,对于示例数据:

CREATE TABLE table_name (ID, Start_Time, End_Time, Down_Mins) AS
SELECT 'ABC123',
       DATE '2022-11-23' + INTERVAL '7' HOUR - NUMTODSINTERVAL(1138.55, 'MINUTE'),
       DATE '2022-11-23' + INTERVAL '7' HOUR + NUMTODSINTERVAL(10232.47 - 1138.55, 'MINUTE'),
       10232.47
FROM   DUAL;

输出:

ID START_TIME END_TIME DOWN_MINS
ABC123 2022-11-22 12:01:27 2022-11-23 07:00:00 1138.55
ABC123 2022-11-23 07:00:00 2022-11-24 07:00:00 1440
ABC123 2022-11-24 07:00:00 2022-11-25 07:00:00 1440
ABC123 2022-11-25 07:00:00 2022-11-26 07:00:00 1440
ABC123 2022-11-26 07:00:00 2022-11-27 07:00:00 1440
ABC123 2022-11-27 07:00:00 2022-11-28 07:00:00 1440
ABC123 2022-11-28 07:00:00 2022-11-29 07:00:00 1440
ABC123 2022-11-29 07:00:00 2022-11-29 14:33:55 453.916666666666666666666666666666666667

fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2017-12-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多