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') )
希望这对您有所帮助 :)
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') )
希望这对您有所帮助 :)