如何按 SQL 中的字符串列进行排序?
How to ORDER BY String column in SQL?
我有一个带有 ID 和 Slot_label 列的 table。我在 Slot Label 列中有不同的时间段,我想从最低时间到最高时间段对它们进行排序。时隙在数据库中保存为字符串值。以下是我的专栏如何处理 运行 这个查询:
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:00 上午 - 8:20 一直到 11:00 上午 - 11:20 上午。由于我没有任何其他可以订购的列,我如何才能让它发挥作用?如果有人可以帮助,请告诉我。
如果您的插槽之间没有重叠,那么您可以拉出第一个时间戳并将其用于排序。如果您需要考虑两个端点,那么它显然会变得更加复杂,但仍然可行。
在我的示例中,我在输出中保留了提取的时间值,因此您可以看到它:
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 标志然后填充第一个时间戳来避免任何数据类型更改:
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');
丑陋的我同意,但像这样的东西有效:
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),':','.'));
我有一个带有 ID 和 Slot_label 列的 table。我在 Slot Label 列中有不同的时间段,我想从最低时间到最高时间段对它们进行排序。时隙在数据库中保存为字符串值。以下是我的专栏如何处理 运行 这个查询:
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:00 上午 - 8:20 一直到 11:00 上午 - 11:20 上午。由于我没有任何其他可以订购的列,我如何才能让它发挥作用?如果有人可以帮助,请告诉我。
如果您的插槽之间没有重叠,那么您可以拉出第一个时间戳并将其用于排序。如果您需要考虑两个端点,那么它显然会变得更加复杂,但仍然可行。
在我的示例中,我在输出中保留了提取的时间值,因此您可以看到它:
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 标志然后填充第一个时间戳来避免任何数据类型更改:
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');
丑陋的我同意,但像这样的东西有效:
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),':','.'));