数据类型 varchar2 oracle 21c 中的求和列

问题描述 投票:0回答:2

我的问题是关于收集时间列的可能性,特别是因为数据类型是

varchar2

CREATE TABLE t_video 
(
    video_id NUMBER NOT NULL ENABLE, 
    video_duration VARCHAR2(30 BYTE), 
    object_video VARCHAR2(1000 BYTE), 

    CONSTRAINT T_VIDEO_PK PRIMARY KEY ( VIDEO_ID )
); 

INSERT INTO t_video (video_id, video_duration, object_video)
VALUES (1,'00:12:20',song); 
INSERT INTO t_video (video_id, video_duration, object_video)   
VALUES (2,'02:50:30',film);

然后我尝试并成功解决了问题如下:

-- code sum hours , minutes, seconds in three column
SELECT
    SUM(to_char(substr(video_duration, - 8, 2))) AS hours,
    SUM(to_char(substr(video_duration, - 5, 2))) / 60 AS minutes,
    SUM(to_char(substr(video_duration, - 2, 2))) / 60 / 60 AS seconds 
FROM 
    t_video;

-- code sum hours , minutes, seconds in one column
SELECT
    id_user,
    SUM(ROUND(h1 + h2 + h3, 2)) AS total_hours   
FROM 
    (SELECT                                  
         id_user,                               
         to_char(substr(video_duration, -8, 2)) AS h1,                                  
         to_char(substr(video_duration, -5, 2)) / 60 AS h2,                                 
         to_char(substr(video_duration, -2, 2)) / 60 / 60 AS h3
     FROM                                
         t_video)
GROUP BY
    ROLLUP(id_user);

我只将时间转换为HH24,得到了所需的结果,如下:

  SELECT id_user,
    CAST(SUM(
    EXTRACT(HOUR FROM 
    video_duration) * 60 * 60 + 
    EXTRACT(MINUTE FROM 
    video_duration) * 60 + 
    EXTRACT(SECOND FROM 
    video_duration)) *
    INTERVAL '24' SECOND AS 
    INTERVAL DAY(1) TO 
    SECOND(0)) AS 
    total_duration
 FROM
 t_video
 GROUP BY ROLLUP(id_user);


 RESULT
 id_user     video_duration
 -------     ------------------
 10          + 241 07: 39:  36
 ------------------------------
 20          + 75 13: 40: 00
 ------------------------------
 NULL        + 316 21: 19: 36
sql oracle datetime
2个回答
2
投票

如果您要存储时间,您可以使用

INTERVAL DAY(0) TO SECOND(0)
数据类型(而不是字符串),然后您的查询可以是:

SELECT video_id,                               
       SUM(
         EXTRACT(HOUR   FROM video_duration) * 60 * 60
       + EXTRACT(MINUTE FROM video_duration) * 60
       + EXTRACT(SECOND FROM video_duration)
       ) * INTERVAL '1' SECOND AS total_duration
FROM   t_video
GROUP BY ROLLUP(video_id);

对于样本数据:

CREATE TABLE t_video 
(
  video_id       NUMBER NOT NULL ENABLE, 
  video_duration INTERVAL DAY(0) TO SECOND(0), 
  object_video   VARCHAR2(1000 BYTE), 
  CONSTRAINT T_VIDEO_PK PRIMARY KEY ( VIDEO_ID )
);

INSERT INTO t_video (video_id, video_duration, object_video)
VALUES (1, INTERVAL '00:12:20' HOUR TO SECOND,'song');

INSERT INTO t_video (video_id, video_duration, object_video)
VALUES (2, INTERVAL '02:50:30' HOUR TO SECOND,'film');

输出:

视频_ID TOTAL_DURATION
1 +000000000 00:12:20.000000000
2 +000000000 02:50:30.000000000
+000000000 03:02:50.000000000

如果您想以不同的方式格式化它,您可以从默认的

INTERVAL DAY(9) TO SECOND(9)
转换为精度更小的间隔,例如
INTERVAL DAY(1) TO SECOND(0)
:

SELECT video_id,                               
       CAST(
         SUM(
           EXTRACT(HOUR   FROM video_duration) * 60 * 60
         + EXTRACT(MINUTE FROM video_duration) * 60
         + EXTRACT(SECOND FROM video_duration)
         ) * INTERVAL '1' SECOND
         AS INTERVAL DAY(1) TO SECOND (0)
       ) AS total_duration
FROM   t_video
GROUP BY ROLLUP(video_id);
视频_ID TOTAL_DURATION
1 +0 00:12:20
2 +0 02:50:30
+0 03:02:50

小提琴


0
投票

最好的办法是将列的类型更改为

interval day to second
。然后你就可以使用Oracle内置的时间间隔函数。

-- Make a new interval day to second column.
alter table t_video add video_duration_new interval day to second;

-- Translate your string durations into intervals.
-- to_dsinterval requires a day, so we add 0 days. This assumes all your video durations are all HH:MM:SS
update t_video set video_duration_new = to_dsinterval(concat('0 ', video_duration));

-- Drop the old column.
alter table t_video drop column video_duration;

-- Replace it with the interval column.
alter table t_video rename column video_duration_new to video_duration;

现在使用

extract
即可轻松获取小时数。

select extract(hour from video_duration) from t_video;

这也可以为性能建立索引,并将检查值的格式是否正确。

示范.

© www.soinside.com 2019 - 2024. All rights reserved.