我有一个带ID和Slot_label列的表。我在Slot Label列中有不同的时隙,我想从最低时间到最高时隙订购它们。时隙在DB中保存为字符串值。以下是运行此查询后我的列的显示方式:
Select *
From EVENT_SLOTS
Order By Slot_Label
ID TIME SLOTS
1778 10:00 AM - 10:20 AM
1776 10:20 AM - 10:40 AM
1779 10:40 AM - 11:00 AM
1780 11:00 AM - 11:20 AM
1781 8:00 AM - 8:20 AM
1777 8:20 AM - 8:40 AM
1782 8:40 AM - 9:00 AM
1775 9:00 AM - 9:20 AM
1774 9:20 AM - 9:40 AM
1783 9:40 AM - 10:00 AM
我希望我的时段从早上8点到早上8点20分一直到上午11点到凌晨11点20分。我怎么能让这个工作,因为我没有任何其他我可以订购的列?如果有人可以帮忙,请告诉我。
答案 0 :(得分:1)
如果您的插槽之间没有重叠,那么您可以拉出第一个时间戳并将其用于订购。如果你需要考虑两个端点,那么它显然会变得更复杂,但仍然可行。
在我的示例中,我将提取的时间值保留在输出中,以便您可以看到它:
with dat as (
SELECT 1778 ID, '10:00 AM - 10:20 AM' slot_label from dual union all
SELECT 1776, '10:20 AM - 10:40 AM' from dual union all
SELECT 1779, '10:40 AM - 11:00 AM' from dual union all
SELECT 1780, '11:00 AM - 11:20 AM' from dual union all
SELECT 1781, '8:00 AM - 8:20 AM' from dual union all
SELECT 1777, '8:20 AM - 8:40 AM' from dual union all
SELECT 1782, '8:40 AM - 9:00 AM' from dual union all
SELECT 1775, '9:00 AM - 9:20 AM' from dual union all
SELECT 1774, '9:20 AM - 9:40 AM' from dual union all
SELECT 1783, '9:40 AM - 10:00 AM' from dual )
select id, slot_label, substr(slot_label, 1, instr(slot_label,'M')) first_time
from dat
order by to_Date(substr(slot_label, 1, instr(slot_label,'M')),'HH:MI AM');
ID, SLOT_LABEL, FIRST_TIME
1781, 8:00 AM - 8:20 AM, 8:00 AM
1777, 8:20 AM - 8:40 AM, 8:20 AM
1782, 8:40 AM - 9:00 AM, 8:40 AM
1775, 9:00 AM - 9:20 AM, 9:00 AM
1774, 9:20 AM - 9:40 AM, 9:20 AM
1783, 9:40 AM - 10:00 AM, 9:40 AM
1778, 10:00 AM - 10:20 AM, 10:00 AM
1776, 10:20 AM - 10:40 AM, 10:20 AM
1779, 10:40 AM - 11:00 AM, 10:40 AM
1780, 11:00 AM - 11:20 AM, 11:00 AM
要获得第二个时间戳,以备需要时使用:
with dat as (
SELECT 1778 ID, '10:00 AM - 10:20 AM' slot_label from dual union all
SELECT 1776, '10:20 AM - 10:40 AM' from dual union all
SELECT 1779, '10:40 AM - 11:00 AM' from dual union all
SELECT 1780, '11:00 AM - 11:20 AM' from dual union all
SELECT 1781, '8:00 AM - 8:20 AM' from dual union all
SELECT 1777, '8:20 AM - 8:40 AM' from dual union all
SELECT 1782, '8:40 AM - 9:00 AM' from dual union all
SELECT 1775, '9:00 AM - 9:20 AM' from dual union all
SELECT 1774, '9:20 AM - 9:40 AM' from dual union all
SELECT 1783, '9:40 AM - 10:00 AM' from dual )
select id
, slot_label
, substr(slot_label, 1, instr(slot_label,'M')) first_time
, substr(slot_label, instr(slot_label,'-')+2) last_time
from dat
order by to_Date(substr(slot_label, 1, instr(slot_label,'M')),'HH:MI AM')
,to_Date(substr(slot_label, instr(slot_label,'-')+2),'HH:MI AM')
要回复您的评论,是的,有很多选项可供选择。例如,您可以通过提取第一个AM / PM标志然后lpadding第一个时间戳来避免任何dataype更改:
select id
, slot_label
, substr(slot_label, instr(slot_label,'M')-1,2) First_ampm
, lpad(substr(slot_label, 1, instr(slot_label,' ')-1),10,'0') first_time
from dat
order by substr(slot_label, instr(slot_label,'M')-1,2)
, lpad(substr(slot_label, 1, instr(slot_label,' ')-1),10,'0');
答案 1 :(得分:1)
丑陋我同意但这样的事情有效:
with myTestCase as
(
select '8:00 PM - 8:20 PM' data from dual union all
select '10:00 AM - 10:20 AM' data from dual union all
select '10:30 AM - 10:20 AM' data from dual union all
select '8:00 AM - 8:20 AM' from dual
)
select t.*
from myTestCase t
order by case when instr(substr(t.data,1,9),'PM') != 0 then 12 else 0 end +
to_number(replace(substr(t.data, 1, instr(t.data,' ') - 1),':','.'));