需要一些关于此查询的帮助,我只是想知道我正在做的事情是好还是我需要JOIN才能让它变得更好。对不起,如果这是一个愚蠢的问题,但我很担心,因为我查询相同的表三次。提前致谢
Select *
from TableA
where (A_id in (1, 2, 3, 4)
and flag = 'Y') or
(A_id in
(select A_id from TableB
where A_id in
(Select A_id from TableA
where (A_id in (1, 2, 3, 4)
and flag = 'N')
group by A_id
having sum(qty) > 0)
)
TableA和TableB之间的关系是一对多
条件或逻辑:
答案 0 :(得分:2)
你的方法确实太复杂了。选择A其中flag = Y或相关B的总和> 0.在子查询中执行后者。
select *
from a
where a_id in (1,2,3,4)
and
(
flag = 'Y'
or
(select sum(qty) from b where b.a_id = a.a_id) > 0
)
答案 1 :(得分:1)
您所提出的查询没有什么严重错误,但可以进行改进。如果你移动测试Flag =' N'进入TableA中的第一个选择并将TableB中的选择与TableA中的第一个选择相关联,然后您可以省去TableA中的第二个选择:
Select *
from TableA A
where A_id in (1, 2, 3, 4)
and (flag = 'Y'
or (flag = 'N'
and A_id in (select A_id
from TableB B
where b.A_id = a.A_id
group by A_id
having sum(qty) > 0))
);
这将消除对TableA的额外查找,以获取应该已知的信息。第二,因为TableA.A_Id现在与TableB.A_Id相关,A_Id in (...)
可以更改为exists子句:
Select *
from TableA A
where A_id in (1, 2, 3, 4)
and (flag = 'Y'
or (flag = 'N'
and exists (select A_id
from TableB B
where b.A_id = a.A_id
group by A_id
having sum(qty) > 0))
);
这可能(取决于数据库类型)通知数据库查询优化器它可以在找到第一行后停止从TableB中检索行。
在一个小型无索引样本数据集的Oracle数据库中,这两个变化削减了查询成本的25%,因此性能提升可能很大。
答案 2 :(得分:-1)
您是否可以将此查询拆分为存储过程?
在示例中:
DELIMITER $$
CREATE FUNCTION flaggedSelection ( my_flag varchar(1) )
RETURNS varchar(255) -- TODO: change to appropriate output
BEGIN
DECLARE return_value varchar(255); -- TODO: change to appropriate output
IF flag = 'Y'
THEN
-- Performe select without further checks
-- return_value = QUERY;
ELSE
-- Refer TableB to see if sum of the qty column is greater than 0
-- return_value = QUERY;
END IF;
RETURN return_value;
END; $$
DELIMITER;