我正在尝试编写两个 SQL 语句。第一个将在晚上 11 点到早上 6 点之间显示,第二个将在晚上 11 点到早上 6 点之间显示 NOT。
我想弄清楚的是,当我说不在之间
WHERE TO_CHAR(MOPACTIVITY.MOPSTART, 'hh24:mi') NOT BETWEEN '23:00' AND '06:00'
我得到了“23:00”和“06:00”之间的记录。这似乎与我在 SQL 中要求的相反。那是怎么回事?
我正在尝试编写两个 SQL 语句。第一个将在晚上 11 点到早上 6 点之间显示,第二个将在晚上 11 点到早上 6 点之间显示 NOT。
我想弄清楚的是,当我说不在之间
WHERE TO_CHAR(MOPACTIVITY.MOPSTART, 'hh24:mi') NOT BETWEEN '23:00' AND '06:00'
我得到了“23:00”和“06:00”之间的记录。这似乎与我在 SQL 中要求的相反。那是怎么回事?
一种解决方案是使用'SSSSS'
格式掩码。它显示午夜后的秒数,非常适合处理时间,而与日期元素无关。
06:00 至 23:00 之间是
select * from t23
where to_number(to_char(some_date_coll, 'SSSSS')) is between (6*60*24) and (23*60*24);
23:00 至 06:00 之间是
select * from t23
where to_number(to_char(some_date_coll, 'SSSSS')) < (6*60*24)
or to_number(to_char(some_date_coll, 'SSSSS')) > (23*60*24);
或者在第一个查询中使用 NOT BETWEEN。
我将算术保留为扩展形式,因为它比硬编码的秒数更容易理解(和修改)。
关于围绕索引列包装函数的性能影响的常见警告适用于此处。
我不确定您对“BETWEEN”的使用是否符合您的意图。我担心的是“介于”是“包含”两个指定值。通常在过滤日期时,您需要一个不包括至少一个边界的开放式间隔。
例如,在您的问题中, between 将检索/省略 06:00 和 23:00 分钟。如下所示,以说明我的观点。
使用“测试数据设置”下面的部分,我构建了一个边缘案例测试数据集。
这是两个查询的输出:
查询 BETWEEN 06 和 23
select
m.mopstart
from
mopactivity m
where 1=1
and to_char(m.mopstart, 'HH24:MI') between '06:00' and '23:00'
order by
m.mopstart
;
10-SEP-02 06.00.00.000000000 AM
10-SEP-02 06.01.00.000000000 AM
10-SEP-02 10.59.00.000000000 PM
10-SEP-02 11.00.00.000000000 PM <-- Did you really want 23:00 record here?
查询 NOT BETWEEN 06 和 23
select
m.mopstart
from
mopactivity m
where 1=1
and to_char(m.mopstart, 'HH24:MI') NOT between '06:00' and '23:00'
order by
m.mopstart
;
10-SEP-02 12.00.00.000000000 AM
10-SEP-02 05.59.00.000000000 AM
10-SEP-02 11.01.00.000000000 PM
测试数据设置 ::
drop table mopactivity
;
create table mopactivity
(
mopstart timestamp NOT NULL
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 22:59', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 23:00', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 23:01', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 05:59', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 06:00', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 06:01', 'DD-Mon-RR HH24:MI')
)
;
insert into mopactivity
values(
TO_TIMESTAMP ('10-Sep-02 00:00', 'DD-Mon-RR HH24:MI')
)
;
commit
;
你想要的代码是:
WHERE TO_CHAR(MOPACTIVITY.MOPSTART, 'hh24:mi') BETWEEN 'o6:00' AND '23:00'
和:
WHERE TO_CHAR(MOPACTIVITY.MOPSTART, 'hh24:mi') not BETWEEN '06:00' AND '23:00'
between
and运算符总是假设第not between
一个界限小于第二个界限。所以没有任何匹配:
where x between 2 and 1
一切都匹配:
where x not between 2 and 1
另一种写法是使用小时:
WHERE hour(MOPACTIVITY.MOPSTART) between 6 and 23 - 1
第二个是:
where hour(MOPACTIVITY.MOPSTART) NOT BETWEEN 6 and 23 - 1
hour()
使用和您的配方之间存在差异。例如23:00:10
6-23 的时间与您的时间匹配,但与此版本不匹配。