Oracle 中的数据库查询

DB QUERY IN ORACLE

SELECT 
    BILLS.* 
FROM 
    BATELCO_BILLS_S BILLS 
INNER JOIN 
(
    SELECT 
         BTL_BILL_I_NUMBER, 
         MAX(R_MODIFY_DATE) AS MAXDATETIME 
    FROM 
        BATELCO_BILLS_S  
    GROUP BY 
         BTL_BILL_I_NUMBER
) GROUPEDBILLS
    ON BILLS.BTL_BILL_I_NUMBER = GROUPEDBILLS.BTL_BILL_I_NUMBER AND
       BILLS.R_MODIFY_DATE = GROUPEDBILLS.MAXDATETIME 
WHERE 
    (BILLS.BTL_BILL_I_CPR = :B3 OR BILLS.BTL_BILL_C_CPR = :B3) AND
    (TO_DATE(BTL_BILL_I_DATE) BETWEEN TO_DATE(:B2, 'dd/mm/yyyy') AND
     TO_DATE(:B1, 'dd/mm/yyyy') OR
     TO_DATE(BTL_BILL_C_DATE) BETWEEN TO_DATE(:B2, 'dd/mm/yyyy') AND
     TO_DATE(:B1, 'dd/mm/yyyy'))

请帮助通过避免连接来优化查询,以便需要 GROUP BY。

避免重复 BTL_BILL_I_NUMBER 并获取结果。

您可以使用解析函数重写它,例如 ROW_NUMBER:

SELECT *
FROM
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY BTL_BILL_I_NUMBER
                           ORDER BY R_MODIFY_DATE DESC) rn
    FROM BATELCO_BILLS_S 
    WHERE 
        (BTL_BILL_I_CPR = :B3 OR BTL_BILL_C_CPR = :B3) AND
        (TO_DATE(BTL_BILL_I_DATE) BETWEEN TO_DATE(:B2, 'dd/mm/yyyy') AND
         TO_DATE(:B1, 'dd/mm/yyyy') OR
         TO_DATE(BTL_BILL_C_DATE) BETWEEN TO_DATE(:B2, 'dd/mm/yyyy') AND
         TO_DATE(:B1, 'dd/mm/yyyy'))
) t
WHERE rn = 1;

我不是 Oracle 语法专家,我上面的 SELECT * 调用可能不起作用。如果没有,那么您可以(并且应该)列出您实际想要 select.

的列

我不是 Oracle 专家,但我会这样做:

  • 避免在选定的列中使用 *,而是提及您需要的每一列;
  • 无需加入。您正在处理相同的 table(参见下面的示例);
  • 为where子句中使用的列添加索引

SELECT BILLS.btl_bill_i_number, Max(r_modify_date) AS MAXDATETIME 
FROM   batelco_bills_s BILLS 
GROUP  BY btl_bill_i_number        
WHERE  ( BILLS.btl_bill_i_cpr = :B3 
OR BILLS.btl_bill_c_cpr = :B3 ) 
AND ( To_date(btl_bill_i_date) BETWEEN To_date(:B2, 'dd/mm/yyyy') AND To_date(:B1, 'dd/mm/yyyy') 
OR To_date(btl_bill_c_date) BETWEEN To_date(:B2, 'dd/mm/yyyy') AND 
To_date(:B1, 'dd/mm/yyyy') )

希望这对您有所帮助 :)