我想显示所有购买和未购买此类物品的物品和客户名称列表。列显示项目、项目名称、已购买的客户名称和未购买的客户姓名。在SQL中,它看起来是这样的。
SELECT field1,field2,field3
FROM tbl1 JOIN tbl2 on ...
WHERE field3 NOT IN (
SELECT distinct field3 FROM tbl3 JOIN tbl4 on ...
WHERE ...)
这里有4张表
customers orders orderlines items
custid|name| orderid|custid| orderid|itemid| itemid|name
规则#1——进度不是SQL。你越努力让它成为SQL,你就会越不高兴。
4GL引擎中对"嵌入式"SQL-89的支持非常有限。如果你因为更喜欢SQL而尝试使用它,你会很快变得非常沮丧。它偶尔对非常快速的&脏的ad-hoc查询,但在其他方面没有用处。
SQL和4GL之间没有直接的转换。
4gl中的查询是非常过程化的。你的问题有点不清楚,但你可以尝试类似的方法:
for each customer no-lock:
for each order no-lock where order.custNum = customer.custNum:
for each orderLine no-lock where orderLine.orderNum = order.orderNum:
display customer.custName order.orderStat orderLine.description.
end.
end.
end.
这个例子非常粗糙——4gl支持更多的功能,包括动态查询和OO构造,但还不清楚您实际需要什么。
您可以使用join编写上面的代码,但对于初学者来说不太清楚:
for each customer no-lock,
each order no-lock where order.custNum = customer.custNum,
each orderLine no-lock where orderLine.orderNum = order.orderNum:
display customer.custName order.orderStat orderLine.description.
end.
4gl代码不倾向于使用很多复杂的查询。它们通常是按程序构建的,可能涉及临时表。
索引是非常重要的。与许多SQL引擎不同,4gl使用静态的、基于规则的编译时优化器。它对数据分布一无所知,并根据规则选择索引。这可能会有所帮助:
http://pugchallenge.org/downloads2014/374_Still_Dont_Know_About_Indices_PCA2014.pdf
如果您想选择不在子查询中的记录,CAN-FIND()函数可能会有所帮助,尽管它对性能不是很好。它通常会导致表格扫描。
即
for each customer no-lock where not can-find( first order where order.custNum = customer.custNum ):
/* customers with no orders... */
end.