如何在此查询中使用count语句?

时间:2019-09-26 09:28:36

标签: sql

我必须显示一艘船的日常起重机工作时间和总箱数。
例如,名为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

有什么方法可以显示FIRSTLIFTLASTLIFT之间的总框?

编辑: 这是我得到的样本数据

第一升降机:最后升降机: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')

3 个答案:

答案 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