在三个where语句中加入两个table,count列行

时间:2017-05-08 17:35:49

标签: sql oracle

我有一个表lot_bill_of_operations,其中包含行和表lot_bill_of_lots_serial_xref,其中包含序列号和时间戳列。这些表与主键bol_id相关联。

我正在尝试计算逐行传递三个班次的序列号,但每个子查询的结果都相同。

以下是查询:

select lot_bill_of_operations.wc_line_code,

(select  count(part_sn) from lot_bill_of_lots_serial_xref
  where lot_bill_of_lots_serial_xref.time_stamp between '07-MAY-17 06:00:00'
    and '07-MAY-17 14:00:00'
  group by lot_bill_of_operations.wc_line_code)firstshift,

(select  count(part_sn) from lot_bill_of_lots_serial_xref
  where lot_bill_of_lots_serial_xref.time_stamp between '07-MAY-17 14:00:00'
    and '07-MAY-17 22:00:00'
  group by lot_bill_of_operations.wc_line_code)secondshift,

(select  count(part_sn) from lot_bill_of_lots_serial_xref
  where lot_bill_of_lots_serial_xref.time_stamp between '07-MAY-17 22:00:00'
    and '08-MAY-17 06:00:00'
  group by lot_bill_of_operations.wc_line_code)thirdshift

FROM lot_bill_of_operations inner JOIN lot_bill_of_lots_serial_xref
    ON lot_bill_of_operations.bol_id = lot_bill_of_lots_serial_xref.bol_id
group by lot_bill_of_operations.wc_line_code

以下是获得的结果:

enter image description here

我做错了什么?

3 个答案:

答案 0 :(得分:2)

看起来您需要条件计数,您可以使用案例表达式获取:

PATCH ../tables/{id|name}/columns/{id}

我已切换到时间戳文字,因为您依靠NLS设置将字符串隐式转换为时间戳。 (或者可能是日期,从你所展示的内容中不清楚)。

但是,使用select lbo.wc_line_code, count(case when lblsx.time_stamp between timestamp '2017-05-07 06:00:00' and timestamp '2017-05-07 14:00:00' then lblsx.part_sn end) as firstshift, count(case when lblsx.time_stamp between timestamp '2017-05-07 14:00:00' and timestamp '2017-05-07 22:00:00' then lblsx.part_sn end) as secondshift, count(case when lblsx.time_stamp between timestamp '2017-05-07 22:00:00' and timestamp '2017-05-08 06:00:00' then lblsx.part_sn end) as thirdshift from lot_bill_of_operations lbo inner join lot_bill_of_lots_serial_xref lblsx on lbo.bol_id = lblsx.bol_id group by lbo.wc_line_code; 表示期间略有重叠,因此您可能真的需要:

between

您可能还希望将select lbo.wc_line_code, count(case when lblsx.time_stamp >= timestamp '2017-05-07 06:00:00' and lblsx.time_stamp < timestamp '2017-05-07 14:00:00' then lblsx.part_sn end) as firstshift, count(case when lblsx.time_stamp >= timestamp '2017-05-07 14:00:00' and lblsx.time_stamp < timestamp '2017-05-07 22:00:00' then lblsx.part_sn end) as secondshift, count(case when lblsx.time_stamp >= timestamp '2017-05-07 22:00:00' and lblsx.time_stamp < timestamp '2017-05-08 06:00:00' then lblsx.part_sn end) as thirdshift from lot_bill_of_operations lbo inner join lot_bill_of_lots_serial_xref lblsx on lbo.bol_id = lblsx.bol_id group by lbo.wc_line_code; 范围包含为整体过滤器,以减少检查的数据量:

time_stamp

如果您在当天使用此算法,则可以使用日期算术而不是固定值。

答案 1 :(得分:1)

如果没有样本数据,很难理解您的需求,但根据您的查询,我认为您需要以下内容。

  • 还要避免比较字符串的日期。使用日期转换功能 比较to_date / to_timestamp,同时比较日期的准确和 没有模糊的结果。
  • 在给出范围时使用between
  • 使用 表名的别名,以提高可读性。

    select o.wc_line_code
        ,count(case when 
                x.time_stamp between to_date('07-MAY-17 06:00:00','DD-MON-YY HH24:MI:SS') 
                                and  to_date('07-MAY-17 14:00:00','DD-MON-YY HH24:MI:SS')
                then 1) as firstshift
    -- , similary for other shifts
    
    FROM lot_bill_of_operations o 
        inner JOIN 
         lot_bill_of_lots_serial_xref x
        ON o.bol_id = x.bol_id
    group by o.wc_line_code;
    

答案 2 :(得分:0)

尝试以下方法:

select lot_bill_of_operations.wc_line_code
, sum (case when time_stamp between '07-MAY-17 06:00:00' and '07-MAY-17 14:00:00'
 then 1 else 0 end ) firstshift
, sum (case when time_stamp between '07-MAY-17 14:00:00' and '07-MAY-17 22:00:00'
 then 1 else 0 end ) secondshift
, sum (case when time_stamp between '07-MAY-17 22:00:00' and '08-MAY-17 06:00:00'
 then 1 else 0 end ) thirdshift
FROM lot_bill_of_operations inner JOIN lot_bill_of_lots_serial_xref
    ON lot_bill_of_operations.bol_id = lot_bill_of_lots_serial_xref.bol_id
group by lot_bill_of_operations.wc_line_code
;