我正在尝试在Oracle 10g数据库上运行查询以尝试查看2组事务。我想查看今年(2014年)有交易的任何人,这些交易在过去的5年中也有过交易。然后,我想对今年(2014年)有交易的人进行查询,该交易在过去5年内未从我们这里订购。我以为我可以用“IN”和“NOT IN”功能来做到这一点。 'IN'查询运行正常,但'NOT IN'永远不会完成。 DB相当大,这可能就是原因。非常喜欢专家的任何建议!
*注意事项,[TEXT]是我们客户公司名称的描述,有时会计部门没有将此与我们留下NULL值的客户ID联系起来,因此使用TEXT作为我的主要分组似乎有效,尽管名称是朦胧。 CODE_D是一个产品系列,只是为了为名称带来上下文。
以下是我的代码:
SELECT CODE_D, sum(coalesce(credit_amount, 0) - coalesce(debet_amount,0)) as TOTAL
FROM
gen_led_voucher_row_tab
WHERE ACCOUNTING_YEAR like '2014'
and TEXT NOT IN
(select TEXT
from gen_led_voucher_row_tab
and voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
)
GROUP BY CODE_D
ORDER BY TOTAL DESC
答案 0 :(得分:1)
尝试使用LEFT JOIN
代替NOT IN
:
SELECT t1.CODE_D, sum(coalesce(t1.credit_amount, 0) - coalesce(t1.debet_amount,0)) as TOTAL
FROM gen_led_voucher_row_tab AS t1
LEFT JOIN gen_led_voucher_row_tab AS t2
ON t1.TEXT = t2.TEXT
AND t2.voucher_date >= '01-JUN-09'
AND t2.voucher_date < '01-JUN-14'
AND (credit_amount > '1' or debet_amount > '1')
WHERE t2.TEXT IS NULL
AND t1.ACCOUNTING_YEAR = '2014'
GROUP BY CODE_D
ORDER BY TOTAL DESC
另外,请确保TEXT
列上有索引。
答案 1 :(得分:0)
您可以将Not In
子句更改为Where Not Exists
,如下所示,从而提高效果:
Where Not Exists
(
Select 1
From gen_led_voucher_row_tab b
Where voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
And a.Text = b.Text
)
您还需要将第一个表别名为a
,以使其正常工作。从本质上讲,你正在撤回大量数据以丢弃它。 Exists
调用Semi Join
根本不会撤回任何数据,因此您应该看到显着的改进。
修改的
您的查询,截至当前问题的更新应为:
SELECT CODE_D,
sum(coalesce(credit_amount, 0) - coalesce(debet_amount,0)) as TOTAL
FROM gen_led_voucher_row_tab a
Where ACCOUNTING_YEAR like '2014'
And Not Exists
(
Select 1
From gen_led_voucher_row_tab b
Where voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
And a.Text = b.Text
)
GROUP BY CODE_D
ORDER BY TOTAL DESC