最小化oracle数据库查询

时间:2018-06-28 13:15:54

标签: java sql oracle

我有一个Java应用程序,正在执行以下查询以获取数据

SELECT prod.product_id,
       prod.product_name,
       product.stock,
       st.status_code,
       st.status_desc,
       usr1.user_nameas AS soldby,
       usr2.user_nameas soldto
  FROM product prod
  JOIN status ON prod.status_code = st.status_code
  LEFT JOIN user usr1 ON prod.agent_id = usr1.user_id
  LEFT JOIN user usr2 ON prod.buyer_id = usr2.user_id
WHERE condition on dates and PROD.STATUS_CODE IN (<<4 inputs>>)

一旦我得到数据,就遍历每条记录,并获取查询的值并在同一对象中设置

SELECT status_code,
       COUNT(*)
  FROM items
 WHERE returned = 1
   AND product_id =?
-- Cheking the status (which are different from prod status)

SELECT STK.STATUS_CODE, count( itm.*)
  FROM items itm
  JOIN stk stk ON stk.item_id = itm.item_id
 WHERE itm.product_id =?

问题是,如果第一个查询根据日期范围返回了太多记录,我需要遍历/遍历两次和两次,以获取最后两个查询的数据库记录。谁能建议我或给我一些指导,以使我如何最大程度地减少到DB的往返行程,从而一次性获取数据。

我尝试使用 WITH clause 并在product_id上的 dense_rank()上进行分区,但是我失败了,因为它提供的记录比原始记录太多。

仅供参考:我正在使用oracle 12C

任何指针将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:1)

谢谢大家,我终于得到了答案。 这是我遵循的过程,很抱歉,我无权访问整个架构,将在一段时间后发布DDL。

这是我最后写的满足我要求的查询。

    WITH 

PROD_RPT AS (
    SELECT prod.product_id as prodId,
       prod.product_name,
       product.stock,
       st.status_code,
       st.status_desc,
       usr1.user_nameas AS soldby,
       usr2.user_nameas soldto,
       itm.status_code as itmStatus,
       itm. returned as returned,
       stk.status_code as stkStatus
  FROM product prod
  JOIN items itm ON prod.product_id = itm.product_id
  LEFT JOIN stk stk ON st.item_id = itm.item_id
  JOIN status ON prod.status_code = st.status_code
  LEFT JOIN user usr1 ON prod.agent_id = usr1.user_id
  LEFT JOIN user usr2 ON prod.buyer_id = usr2.user_id
  WHERE condition on dates and PROD.STATUS_CODE IN (<<4 inputs>>)
),

ITM_RPT AS (
  SELECT * FROM (
    select count(*) Over(partition by rpt.prodId, rpt.itmStatus ORDER BY rpt.prodId, rpt.itmStatus) cnt,
    row_number() Over(partition by rpt.prodId, rpt.itmStatus ORDER BY rpt.prodId, rpt.itmStatus) rn,
    rpt.*
    FROM PROD_RPT rpt WHERE rpt.returned = 1
  ) where rn = 1
),
ITM_STK_RPT AS (
  SELECT * FROM (
    select count(*) Over(partition by rpt.prodId, rpt.stkStatus ORDER BY rpt.prodId, rpt.stkStatus) cnt,
    row_number() Over(partition by rpt.prodId, rpt.stkStatus ORDER BY rpt.prodId, rpt.stkStatus) rn,
    rpt.*
    FROM PROD_RPT rpt
  ) where rn = 1
)

SELECT * FROM ITM_RPT
UNION ALL 
SELECT * FROM ITM_STK_RPT