我有4张桌子:
create table Product(pCode integer primary key, pName varchar(20), Color varchar(10);
create table Cli(cCode integer primary key, cName varchar(20), city varchar(20));
create table Sale(pOut integer references Product(tCode), cOut integer references Client(cCode), countOut integer, dtOut date, primary key (pOut, kOut);
create table Buy (pIn integer references Product(pCode), cIn integer references Client(cCode), countIn integer, dtIn date, primary key (pIn, kIn);
我需要显示客户的名字不是来自喀山,而是那些在2015年上半年购买一些商品,然后在2015年下半年销售相同商品的客户。
我通过使用视图解决了这个问题。
create view vA as select cCode from Cli where Cli.City <> 'Kazan';
create view vB(cCode, pCode) as select cOut, pOut from Sale where '01.01.2015'<=dtOut AND dtOut<'01.07.2015';
create view vC(cCode, tCode) as select cIn, tIn where '01.07.2015<=dtIn AND dtIn < '01.01.2016';
create view vD as select * from vB inner join vC on vB.cKod=vC.cKod AND vc.pCode=vB.pCode;
create view vE as select * from vD right outer join on vA on vA.cCode=vD.cCode;
create view vF as select distinct c.Knam from Cli as c inner join vE on vE.cCode=c.cCode;
如果我要使用加入存在/不存在会不会有所作为?
例如对于vD - 存在而不是内连接:
create view vD as select * from vB where exists(select * from vC where B.cCode=vC.cCode AND vc.pCode=vB.pCode);
对于vE - 不存在而不是右外连接:
create view vE as select * from vA where not exists(select * from vD where vA.cCode=vD.cCode);
答案 0 :(得分:0)
我认为存在是一种更好的解决方案,因为常识告诉我它应该更快。如果你说&#34;存在&#34;这意味着查询将在找到匹配时停止,但是当您说&#34;不存在时#34;它需要通过所有元素来确保它不存在。
另外,我想鼓励您使用更好的命名,因为查询现在很难阅读。
答案 1 :(得分:0)
这是使用EXPLAIN
我的猜测是,您发现优化程序在INNER JOIN
和WHERE EXISTS
之间选择相同的方法(相反,Right Outer Join
/ Is Null
vs {{1因为它们在这种情况下大致相同,而且Postgres有一个很好的优化器。
Here's a good example某人正在为您的Not Exists
查询执行完全相同的测试,他的结果是Postgres为这两种方法选择了vE
。
最后,如果您不确定哪条路线是最佳路线,那么只需写下两条路线,看看效果最好的路线。查询运行后检查统计信息并查看Hash Anti Join
。