我有一个输入:
01.03.16 15:48:45.772000000
01.03.16 15:48:49.924000000
01.03.16 21:31:08.320000000
01.03.16 21:56:05.201000000
02.03.16 00:11:10.552000000
02.03.16 00:11:11.652000000
02.03.16 01:31:14.359000000
02.03.16 21:41:11.059000000
03.03.16 00:11:06.850000000
03.03.16 11:05:20.343000000
03.03.16 16:07:07.148000000
04.03.16 18:15:14.460000000
04.03.16 18:55:39.206000000
05.03.16 00:15:21.457000000
05.03.16 00:20:14.908000000
05.03.16 00:50:15.641000000
07.03.16 08:45:19.526000000
07.03.16 21:30:20.562000000
07.03.16 21:45:20.402000000
08.03.16 00:11:12.163000000
08.03.16 14:37:46.607000000
08.03.16 23:16:22.713000000
08.03.16 23:16:22.715000000
现在,我们的想法是按日期分组,并在下午6点30分之前和之后计算行数。 。结果应该是:
date before after
01.03.16 2 2
02.03.16 3 1
03.03.16 3 0
04.03.16 0 2
05.03.16 3 0
07.03.16 1 2
08.03.16 2 2
如果我按trunc(mytimestamp)
进行分组,并使用case
在select
语句中设置mytimestamp
,我就无法获得正确的结果。
我的实际查询是:
select trunc(tscreate),
to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute as referenz_time,
sum(case when ( tscreate < to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute) then 1 else 0 end) as beforeTS,
sum(case when ( tscreate >= to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute) then 0 else 1 end) as afterTS
from customer
where app = 'abc'
and tscreate >= to_date('01.03.2016','dd.MM.yyyy')
group by trunc(tscreate) order by trunc(tscreate)
beforTS
的值似乎计算正确,但afterTS
始终与beforeTS
相同,但这是不可能的。
答案 0 :(得分:1)
您作为评论发布的查询几乎可以正常工作 - 它不会出错但却无法获得您想要的结果。在第二个case
表达式中,您已将<
更改为>=1
,但您已将then 0 else 1
更改为then 1 else 0
以及和这两个变化相互抵消 - 两者的逻辑结束相同,并且它们都在17:30之前计算时间。
所以只需修复即可得到你想要的结果:
select trunc(tscreate),
to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute as referenz_time,
sum(case when ( tscreate < to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute) then 1 else 0 end) as beforeTS,
sum(case when ( tscreate >= to_timestamp(trunc( trunc(tscreate)),'dd.MM.yy')
+ interval '17' hour + interval '30' minute) then 1 else 0 end) as afterTS
from customer
where app = 'abc'
and tscreate >= to_date('01.03.2016','dd.MM.yyyy')
group by trunc(tscreate)
order by trunc(tscreate);
TRUNC(TSCREATE) REFERENZ_TIME BEFORETS AFTERTS
--------------- ---------------------------- ---------- ----------
01-MAR-16 01-MAR-16 17.30.00.000000000 2 2
02-MAR-16 02-MAR-16 17.30.00.000000000 3 1
03-MAR-16 03-MAR-16 17.30.00.000000000 3 0
04-MAR-16 04-MAR-16 17.30.00.000000000 0 2
05-MAR-16 05-MAR-16 17.30.00.000000000 3 0
07-MAR-16 07-MAR-16 17.30.00.000000000 1 2
08-MAR-16 08-MAR-16 17.30.00.000000000 2 2
我会略微简化它,但其中一些归结为个人品味:
select trunc(tscreate),
cast(trunc(tscreate)
+ interval '17:30' hour to minute as timestamp) as referenz_time,
count(case when tscreate < cast(trunc(tscreate)
+ interval '17:30' hour to minute as timestamp) then 1 end) as beforeTS,
count(case when tscreate >= cast(trunc(tscreate)
+ interval '17:30' hour to minute as timestamp) then 1 end) as afterTS
from customer
where app = 'abc'
and tscreate >= timestamp '2016-03-01 00:00:00'
group by trunc(tscreate)
order by trunc(tscreate);
获得相同的结果。或者,如果您不喜欢间隔,则可以使用日期算术:
select trunc(tscreate),
trunc(tscreate) + 17.5/24 as referenz_time,
count(case when tscreate < cast(trunc(tscreate) + 17.5/24 as timestamp) then 1 end) as beforeTS,
count(case when tscreate >= cast(trunc(tscreate) + 17.5/24 as timestamp) then 1 end) as afterTS
from customer
where app = 'abc'
and tscreate >= timestamp '2016-03-01 00:00:00'
group by trunc(tscreate)
order by trunc(tscreate);
(您甚至可以对提取的时间进行字符串比较,正如David Wallace简要建议的那样,即to_char(tscreate, 'HH24:MI') < '17:30'
。但即使这是24小时的'安全',我更愿意坚持原始数据类型。)
我不确定你真的需要referenz_time
作为时间戳,无论哪种方式用于显示,你都应该明确地格式化日期和时间戳,而不是依赖于NLS设置。
答案 1 :(得分:0)
您仍然可以在任何地方使用trunc(mytimestamp)
:
select to_char(trunc(mytimestamp), 'DD.MM.YYYY')
from my_table
group by trunc(mytimestamp)