我正在使用一个包含标题和持续时间的歌曲数据库。
我需要返回持续时间超过29:59(MM:SS)的所有歌曲。
数据以两种不同的方式格式化。
格式1
表格中的大部分数据都格式化为MM:SS,有些歌曲的格式大于60分钟,例如72:15。
格式2
表格中的其他歌曲格式为HH:MM:SS,其中格式1的示例将改为01:12:15。
我尝试了两种不同类型的查询来解决这个问题。
查询1
以下查询返回我为格式1返回的所有值,但是我找不到为格式2包含值的方法。
select title, duration from songs where
time(cast(duration as time)) >
time(cast('29:59' as time))
查询2
使用下一个查询,我希望使用str_to_date
中的格式说明符来查找格式为HH:MM:SS的结果,但我收到的结果如3:50。解释器假设所有数据都是HH:MM的形式,我不知道如何在不破坏结果的情况下告诉它。
select title, duration from songs where
time(cast(str_to_date(duration, '%H:%i:%s') as time)) >
time(cast(str_to_date('00:29:59', '%H:%i:%s') as time))
我已尝试将第一次调用中的说明符更改为str_to_date
到%i:%s
,这使我的所有值都大于29:59,但不会大于59:59。这比原始查询更糟糕。我还尝试了00:%i:%s
和'00:' || duration, '%H:%i:%s'
。这两个特别会破坏结果,但我现在只是在摆弄。
我彻底难倒,但我确定解决方案很简单。任何帮助表示赞赏。
编辑:以下是评论中提供的一些数据。
show create table
的结果:
CREATE TABLE `songs` (
`song_id` int(11) NOT NULL,
`title` varchar(100) NOT NULL,
`duration` varchar(20) DEFAULT NULL,
PRIMARY KEY (`song_id`),
UNIQUE KEY `songs_uq` (`title`,`duration`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
请记住,列数比我上面描述的多,但为了简单起见,我留下了一些列。我也会将它们留在样本数据中。
示例数据
title duration
(Allegro Moderato) 3:50
Agatha 1:56
Antecessor Machine 06:16
Very Long Song 01:24:16
Also Very Long 2:35:22
答案 0 :(得分:2)
您正在将非结构化数据存储在关系数据库中。这让你不快乐。所以要构建它。
添加TIME列,或将song_id复制到可以加入的一侧的并行时间表中。选择所有两个冒号的持续时间并轻松更新TIME。重复,前置' 00:'所有单结肠持续时间。现在您已经解析了所有行,并且可以安全地忽略持续时间列。
好的,我想你可以构建一个提供UNION所有这两个查询的VIEW,但这很慢且很丑,更好地修复磁盘上的数据。
答案 1 :(得分:0)
忘记时间。转换为秒。这是一种方式:
select s.*
from (select s.*,
( substring_index(duration, ':', -1) + 0 +
substring_index(substring_index(duration, ':', -2), ':', 1) * 60 +
(case when duration like '%:%:%' then substring_index(duration, ':', 1) * 60*60
else 0
end)
) as duration_seconds
from songs s
) s
where duration_seconds > 29*60 + 59;
答案 2 :(得分:0)
select title, duration from songs where
case
when length(duration) - length(replace(duration, ':', '')) = 1
then time_to_sec(duration) > time_to_sec('29:59')
else time_to_sec(duration) > time_to_sec('00:29:59')
end
感谢Gordon Linoff建议我将时间转换为秒。这使事情变得更容易。我刚刚发现他的解决方案有点过于复杂,它通过不使用time_to_sec来重新发明轮子。
输出数据
title duration
21 Album Mix Tape 45:40
Act 1 1:20:25
Act 2 1:12:05
Agog Opus I 30:00
Among The Vultures 2:11:00
Anabasis 1:12:00
Avalanches Mixtape 60:00
Beautiful And Timeless 73:46
Beggars Banquet Tracks 76:07
Bonus Tracks 68:55
Chindogu 66:23
Spun 101:08
注意:戈登提到他不使用time_to_sec的原因是为了超过23小时的歌曲。经过测试,我发现time_to_sec确实支持大于23的小时,就像它支持大于59的分钟一样。
对于其他不符合要求的格式,例如1:4:32(例如01:04:32),它也完全没问题。