我必须显示一艘船的日常起重机工作时间和总箱数。
例如,名为FG1的起重机可以在2019年9月25日晚上8点至2019年9月26日早上3点工作。查询需要显示两个信息,分别是从09/25/2019 8pm到11.59 pm的总计框和从09/26/2019 12 am到3 am的总计框。问题在于它不能正确地计算两个日期之间的总框数。
SELECT SUBSTR (b.user_voy, 1, 12) JPVC
, NVL (SUBSTR (TO_CHAR (MIN (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-') FIRSTLIFT
, NVL (SUBSTR (TO_CHAR (MAX (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-') LASTLIFT
, (
select Count(actual_time)
from tb_gc_odr
where actual_time IS NOT NULL
and equ_no = g.equ_no
and vsl_cd = t.vsl_cd
AND call_year = t.call_year
AND call_seq = t.call_seq
) as COM_TOTAL
, SUBSTR((ROUND((((FLOOR(((MAX(g.actual_time)) - (MIN(g.actual_time))) * 24)) * 60) + (MOD(FLOOR(((MAX(g.actual_time)) - (MIN(g.actual_time))) * 24 * 60), 60))) / 60, 2) || ' '), 1, 18) WH
FROM tb_gc_odr g
, tb_master t
, tb_berthplan b
WHERE 1 = 1
AND g.vsl_cd = t.vsl_cd
AND g.call_year = t.call_year
AND g.call_seq = t.call_seq
AND g.cntr_no = t.cntr_no
AND g.cntr_seq = t.cntr_seq
AND b.call_year = t.call_year
AND b.call_seq = t.call_seq
AND b.vsl_cd = t.vsl_cd
AND g.cntr_seq = t.cntr_seq
AND t.cntr_seq = '0'
AND t.cargo_type <> 'BB'
AND g.equ_no = 'FG1'
AND TO_CHAR(g.actual_time, 'MM/DD/YYYY') between '09/23/2019' and '09/26/2019'
GROUP BY t.vsl_cd
, t.call_year
, t.call_seq
, g.equ_no
, b.user_voy
, TO_CHAR(g.actual_time, 'MM/DD/YYYY')
order by g.equ_no
, FIRSTLIFT
我注意到count语句是错误的
(
select Count(actual_time)
from tb_gc_odr
where actual_time IS NOT NULL
and equ_no = g.equ_no
and vsl_cd = t.vsl_cd
AND call_year = t.call_year
AND call_seq = t.call_seq
) as COM_TOTAL
期望:
JPVC | FIRSTLIFT | LASTLIFT | COM_TOTAL | WH
-----+--------------------+--------------------+-----------+--------
A01 | 09/25/2019 8:00PM | 09/25/2019 11:59PM | 97 | 4 HOURS
A01 | 09/26/2019 12:00AM | 09/26/2019 03:00AM | 100 | 3 HOURS
实际结果:
JPVC | FIRSTLIFT | LASTLIFT | COM_TOTAL | WH
-----+--------------------+--------------------+-----------+--------
A01 | 09/25/2019 8:00PM | 09/25/2019 11:59PM | 197 | 4 HOURS
A01 | 09/26/2019 12:00AM | 09/26/2019 03:00AM | 197 | 3 HOURS
有什么方法可以显示FIRSTLIFT
和LASTLIFT
之间的总框?
编辑: 这是我得到的样本数据
第一升降机:最后升降机:JPVC:工作时间:总计箱
2019-09-23 00:02:07:2019-09-23 04:10:15:19KITN-0518S:4.13:84
2019-09-24 07:37:47:2019-09-24 17:42:03:19KITN-0519S:10.07:210
2019-09-24 21:36:23:2019-09-24 23:59:07:19HBRM-HM134:2.37:177
2019-09-25 00:01:25:2019-09-25 05:34:07:19HBRM-HM134:5.53:177
2019-09-25 09:21:18:2019-09-25 12:28:51:19D112-7262:3.12:110
2019-09-25 15:57:29:2019-09-25 23:57:35:19BDGM-BM193:8:195
2019-09-26 00:00:58:2019-09-26 03:37:30:19BDGM-BM193:3.6:195
新更新:
没关系。已经知道了。需要添加AND TO_CHAR(actual_time,'MM / DD / YYYY')= TO_CHAR(g.actual_time,'MM / DD / YYYY')
答案 0 :(得分:1)
没有样本数据很难回答这个问题,但是您的计算并不将结果限制在您指定的时间。
您需要包含以下内容:
(select Count(actual_time)
from tb_gc_odr
where actual_time IS NOT NULL
and equ_no= g.equ_no
and vsl_cd = t.vsl_cd
AND call_year = t.call_year
AND call_seq = t.call_seq
and actual_time > NVL (SUBSTR (TO_CHAR (MIN (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-')
and actual_time < NVL (SUBSTR (TO_CHAR (MAX (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-')
) as COM_TOTAL,
答案 1 :(得分:0)
如果您可以显示一些样本数据,那么数据看起来如何,那么解决问题就容易一些。 但是我想在使用的SUB查询中添加您必须为DATES添加更多参数的功能,我认为它们正在获取所有数据。
(
select Count(actual_time)
from tb_gc_odr
where actual_time IS NOT NULL
and equ_no = g.equ_no
and vsl_cd = t.vsl_cd
AND call_year = t.call_year
AND call_seq = t.call_seq
AND actual_time between '*datefrom*' and '*dateto*'
) as COM_TOTAL
您必须过滤数据。我试图解决您的问题
答案 2 :(得分:0)
尝试像这样从表tb_gc_odr添加时间分组:
select g.*,case
when to_char(g.actual_time,'hh24mi') <= 300 or to_char(g.actual_time,'hh24mi') >= 2000 then 'group 1'
when to_char(g.actual_time,'hh24mi') > 300 or to_char(g.actual_time,'hh24mi') < 2000 then 'group 2'
end as group_time from tb_gc_odr g
因此,您查询的全案是这样的:
SELECT SUBSTR (b.user_voy, 1, 12) JPVC
, NVL (SUBSTR (TO_CHAR (MIN (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-') FIRSTLIFT
, NVL (SUBSTR (TO_CHAR (MAX (g.actual_time), 'YYYY-MM-DD HH24:MI:SS'), 1, 20),'-') LASTLIFT
, (
select Count(actual_time)
from tb_gc_odr
where actual_time IS NOT NULL
and equ_no = g.equ_no
and vsl_cd = t.vsl_cd
AND call_year = t.call_year
AND call_seq = t.call_seq
) as COM_TOTAL
, SUBSTR((ROUND((((FLOOR(((MAX(g.actual_time)) - (MIN(g.actual_time))) * 24)) * 60) + (MOD(FLOOR(((MAX(g.actual_time)) - (MIN(g.actual_time))) * 24 * 60), 60))) / 60, 2) || ' '), 1, 18) WH
FROM (select g.*,case
when to_char(g.actual_time,'hh24mi') <= 300 or to_char(g.actual_time,'hh24mi') >= 2000 then 'group 1'
when to_char(g.actual_time,'hh24mi') > 300 or to_char(g.actual_time,'hh24mi') < 2000 then 'group 2'
end as group_time from tb_gc_odr g
) g
, tb_master t
, tb_berthplan b
WHERE 1 = 1
AND g.vsl_cd = t.vsl_cd
AND g.call_year = t.call_year
AND g.call_seq = t.call_seq
AND g.cntr_no = t.cntr_no
AND g.cntr_seq = t.cntr_seq
AND b.call_year = t.call_year
AND b.call_seq = t.call_seq
AND b.vsl_cd = t.vsl_cd
AND g.cntr_seq = t.cntr_seq
AND t.cntr_seq = '0'
AND t.cargo_type <> 'BB'
AND g.equ_no = 'FG1'
AND TO_CHAR(g.actual_time, 'MM/DD/YYYY') between '09/23/2019' and '09/26/2019'
GROUP BY t.vsl_cd
, t.call_year
, t.call_seq
, g.equ_no
, b.user_voy
, g.group_time
order by g.equ_no
, FIRSTLIFT