我正在学习Oracle电子商务套件。使用SQL查询,我想获取已启用ASSEMBLY_ITEM
且其作业创建日期在过去3年内的所有项目(BOM
)。我写的查询给了我想要的结果,但不知何故,组件项列表(COMPONENT_ITEM
)具有不完整的数据或(Null
)对于某些项目。例如,我知道的一些项目有5个组件,但在SQL查询输出中,同一个项目显示为具有单个组件。我正在验证Oracle Apps前端部分的数据。
这是我到目前为止的查询:
SELECT DISTINCT BOM.BILL_SEQUENCE_ID,
MSI.ORGANIZATION_ID,
MSI.SEGMENT1 ASSEMBLY_ITEM,
(SELECT SEGMENT1
FROM MTL_SYSTEM_ITEMS_B
WHERE INVENTORY_ITEM_ID=BIC.COMPONENT_ITEM_ID
AND rownum =1
) "COMPONENT_ITEM"
FROM BOM_OPERATIONAL_ROUTINGS BOR,
BOM_BILL_OF_MATERIALS BOM,
BOM_INVENTORY_COMPONENTS BIC,
MTL_SYSTEM_ITEMS_B MSI
WHERE BOR.ASSEMBLY_ITEM_ID = BOM.ASSEMBLY_ITEM_ID
AND BOR.ORGANIZATION_ID = BOM.ORGANIZATION_ID
AND BOM.BILL_SEQUENCE_ID = BIC.BILL_SEQUENCE_ID(+)
AND BOM.ASSEMBLY_ITEM_ID = MSI.INVENTORY_ITEM_ID(+)
AND BOM.ORGANIZATION_ID = MSI.ORGANIZATION_ID
AND MSI.ORGANIZATION_ID IN (203, 204, 328)
AND MSI.BOM_ENABLED_FLAG = 'Y'
AND NVL (MSI.ENABLED_FLAG, 'X') = 'Y'
AND BOR.ASSEMBLY_ITEM_ID IN
(SELECT DISTINCT PRIMARY_ITEM_ID
FROM WIP_DISCRETE_JOBS WDJ
WHERE BOR.ASSEMBLY_ITEM_ID = WDJ.PRIMARY_ITEM_ID
AND WDJ.CREATION_DATE >= ADD_MONTHS(SYSDATE, -12*3)
)
我的查询应返回唯一的程序集项,每个程序集项可能包含一个或多个组件。
理想情况下,我应该获得所有独特的装配项目及其组件项目。我通过删除BOM.BILL_SEQUENCE_ID = BIC.BILL_SEQUENCE_ID (+)
上的联接,并在查询结尾处删除了半联接来实现此目的," AND BOR.ASSEMBLY_ITEM_ID IN
"部分,它基本上过滤了自过去3年以来的结果。
加入部分不是真正的问题。有没有办法根据过去3年创建的项目过滤结果,使用此方法以外的其他内容? 我在这里缺少什么?
答案 0 :(得分:0)
你可以在这里做些好事。
首先,使用ANSI JOINS
。我看到至少你的一些问题是由于LEFT OUTER加入的错误尝试造成的。使用ANSI
语法可以帮助您避免此类问题。
其次,除非您了解为什么有必要,否则请勿使用DISTINCT
。没有必要编写您想要的查询。
第三,您不需要加入BOM_OPERATIONAL_ROUTINGS
- 您不会将其用于任何事情(除非您尝试将其用作过滤器 - 限制为{{1}有路由的?)
第四,使用BOM
代替EXISTS
。 Oracle的优化程序大部分都足够聪明,可以保护您免受IN
过去对您造成的性能损失。尽管如此,IN
更能代表您的意图(imo)并减少对智能优化器的依赖。
最后,获取组件项的EXISTS
是不必要的。您只需要限制ROWNUM=1
。
总而言之,以下查询应该非常接近您所寻找的内容:
ORGANIZATION_ID