数据类型varchar2 oracle 21c中的Sum列

pxiryf3j  于 2023-01-04  发布在  Oracle
关注(0)|答案(2)|浏览(236)

我的问题是关于收集时间列的可能性,特别是因为数据类型是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

谢谢你的帮助,谢谢你,网站管理,🌹►️

yyyllmsg

yyyllmsg1#

如果要存储时间,则可以使用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|总计_持续时间|
| - ------| - ------|
| 1个|+00000000 00分12秒20秒|
| 第二章|+00000000 02时50分30秒|
| * 无效 *| +00000000 03时02分50秒|
如果您想以不同的方式格式化它,可以将默认值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|总计_持续时间|
| - ------| - ------|
| 1个|+0 00时12分20秒|
| 第二章|+0 02时50分30秒|
| * 无效 *| +0 03时02分50秒|
fiddle

avwztpqn

avwztpqn2#

最好的方法是将列的类型更改为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;

这也可以为性能编制索引,并将检查值的格式是否正确。
Demonstration.

相关问题