优化了这个查询

时间:2013-12-07 13:31:10

标签: mysql

具有3个表的结构

Table min consist of matcode,min_qty,jo_no,mr_no
Table min_out_body consist of matcode,out_qty,jo_no,mr_no
Table eu_min_out_body consist of matcode,out_qty,jo_no,mr_no

数据如下:

[min]
matcode       min_qty           jo_no           mr_no
xxx           100               1A              A11
xxx           150               2A              A22

[min_out_body]
matcode       out_qty           jo_no           mr_no
xxx           10                1A              A11
xxx           60                1A              A11
xxx           100               2A              A22

[eu_min_out_body]
matcode       out_qty           jo_no           mr_no
xxx           20                1A              A11
xxx           50                2A              A22

我想要达到的目的是得到一个结果:

matcode        min_qty          jo_no           mr_no          balance
xxx            100              1A              A11            10
xxx            150              2A              A22            0

使用以下代码查询:

SELECT
    min.matcode,
    min.min_qty,
    min.jo_no,
    min.mr_no
    (min.min_qty-(
        select ifnull(sum(out_qty),0) 
        FROM min_out_body 
        WHERE matcode=min.matcode 
        and jo_no=min.jo_no 
        and mr_no=min.mr_no
        )-(
        select ifnull(sum(out_qty),0) 
        FROM eu_min_out_body 
        WHERE matcode=min.matcode 
        and jo_no=min.jo_no 
        and mr_no=min.mr_no
        )
    ) as balance
FROM min
WHERE min.matcode = 'xxx'
    and (min.min_qty - (select
              ifnull(sum(out_qty),0)
            FROM min_out_body
            WHERE matcode = min.matcode
                and jo_no = min.jo_no
                and mr_no = min.mr_no) - (select
                            ifnull(sum(out_qty),0)
                              FROM eu_min_out_body
                              WHERE matcode = min.matcode
                              and jo_no = min.jo_no
                              and mr_no = min.mr_no)) > 0

我可以得到结果,但有没有办法简化查询并缩短处理时间?

1 个答案:

答案 0 :(得分:0)

我看到两个选项,并且根据您处理的数据量可能比其他更好...第一个是更容易阅读,但简化了您的WHERE子句,可能是您想要运行的.. / p>

包装您的查询,但仅限于WHERE MAT_CODE限定符。让“PQ”(PreQuery)返回所有内容 - 所有余额。然后,只需应用WHERE balance> 0对比您的复杂余额计算在where子句中完成了AGAIN。

SELECT PQ.*
   from
      ( SELECT
            min.matcode,
            min.min_qty,
            min.jo_no,
            min.mr_no
            (min.min_qty 
              - ( select ifnull(sum(out_qty),0) 
                    FROM min_out_body 
                   WHERE min_no = min.min_no 
                     and matcode = min.matcode 
                     and jo_no = min.jo_no 
                     and mr_no = min.mr_no )
              - ( select ifnull(sum(out_qty),0) 
                    FROM eu_min_out_body 
                   WHERE min_no=min.min_no 
                     and matcode=min.matcode 
                     and jo_no=min.jo_no 
                     and mr_no=min.mr_no ) ) as balance
           FROM 
              min
           WHERE 
                  min.matcode = 'xxx' ) PQ
   where
      balance > 0

如果是一个更大的数据集,它看起来有点大,因为它根据你的内部字段选择处理的组件按照“out_body”表和组预先聚合查询ONCE。然后LEFT JOIN到那些表。这种方法的好处是它不会在每个记录的基础上运行内部选择sum(),如果你有1000个记录要经过,可能会为你节省更多的时间......特别是如果它去了通过MIN_OUT_BODY和EU_MIN_OUT_BODY。

通过Left-Join,它是或不是,并且IFNULL()以相同的方式工作,然后WHERE子句是对余额的简单可读计算,不必再次重新查询。

SELECT
      min.matcode,
      min.min_qty,
      min.jo_no,
      min.mr_no,
      min.min_qty - ifnull( MOB1.out_qty, 0 ) - ifnull( EMOB1.out_qty, 0 ) balance
   from
      min
         LEFT JOIN ( select 
                      mob.matcode,
                      mob.min_no,
                      mob.jo_no,
                      mob.mr_no,
                      SUM( mob.out_qty ) out_qty
                   from
                      min_out_body mob
                   where
                      mob.matcode = 'xxx'
                   group by
                      mob.matcode,
                      mob.min_no,
                      mob.jo_no,
                      mob.mr_no ) MOB1
            ON min.matcode = MOB1.matcode
            AND min.min_no = MOB1.min_no
            AND min.jo_no = MOB1.jo_no
            AND min.mr_no = MOB1.mr_no 

         LEFT JOIN ( select 
                      Emob.matcode,
                      Emob.min_no,
                      Emob.jo_no,
                      Emob.mr_no,
                      SUM( Emob.out_qty ) out_qty
                   from
                      eu_min_out_body Emob
                   where
                      Emob.matcode = 'xxx'
                   group by
                      Emob.matcode,
                      Emob.min_no,
                      Emob.jo_no,
                      Emob.mr_no ) EMOB1
            ON min.matcode = EMOB1.matcode
            AND min.min_no = EMOB1.min_no
            AND min.jo_no = EMOB1.jo_no
            AND min.mr_no = EMOB1.mr_no 
   where
          min.matcode = 'xxx'
      AND min.min_qty - ifnull( MOB1.out_qty, 0 ) - ifnull( EMOB1.out_qty, 0 ) > 0