2016-09-22 109 views
0

我有一个SQL查询,其中我试图获取物料及其物料清单(BOM)已启用且其创建日期与过去三年一致的物料。 问题是每个项目及其组件列表都会重复出现。假设一个项目有5个组件,我用特定的项目号码进行查询。我得到35行(7组重复5组)。但是,如果我使用特定的WIP_ENTITY_NAME进行查询,或者如果使用DISTINCT,则会得到完美的5行数据。我需要获取这些数据(5行,不重复),当我查询一个特定的物品编号时。 下面是查询:将WIP_DISCRETE_JOBS加入到物料清单表

SELECT * 
FROM BOM_BILL_OF_MATERIALS BOM, 
    BOM_INVENTORY_COMPONENTS BIC, 
    BOM_COMPONENTS_B BCB, 
    BOM_OPERATIONAL_ROUTINGS_V BORV, 
    BOM_OPERATION_SEQUENCES_V BOSV, 
    BOM_STRUCTURES_B BSB, 
    BOM_STRUCTURE_TYPES_B BST, 
    MTL_SYSTEM_ITEMS_B MSI, 
    MTL_SYSTEM_ITEMS_TL MSIT, 
    ORG_ORGANIZATION_DEFINITIONS OOD, 
    WIP_DISCRETE_JOBS_V WDJV 
WHERE BOM.BILL_SEQUENCE_ID = BIC.BILL_SEQUENCE_ID 
AND BIC.COMPONENT_SEQUENCE_ID = BCB.COMPONENT_SEQUENCE_ID 
AND BCB.BILL_SEQUENCE_ID  = BSB.BILL_SEQUENCE_ID 
AND BOM.STRUCTURE_TYPE_ID  = BST.STRUCTURE_TYPE_ID 
AND BOM.ASSEMBLY_ITEM_ID  = MSI.INVENTORY_ITEM_ID 
AND BOM.ORGANIZATION_ID  = MSI.ORGANIZATION_ID 
AND BOSV.ROUTING_SEQUENCE_ID = BORV.ROUTING_SEQUENCE_ID 
AND BORV.ASSEMBLY_ITEM_ID = BOM.ASSEMBLY_ITEM_ID 
AND BORV.ORGANIZATION_ID  = BOM.ORGANIZATION_ID 
AND MSI.INVENTORY_ITEM_ID = MSIT.INVENTORY_ITEM_ID 
AND MSI.ORGANIZATION_ID  = MSIT.ORGANIZATION_ID 
AND MSIT.ORGANIZATION_ID  = OOD.ORGANIZATION_ID 
AND MSIT.LANGUAGE   = USERENV('LANG') 
AND sysdate BETWEEN BCB.EFFECTIVITY_DATE AND NVL(BCB.DISABLE_DATE, sysdate) 
AND MSI.BOM_ENABLED_FLAG   = 'Y' 
AND NVL(MSI.ENABLED_FLAG,'X')  ='Y' 
AND OOD.ORGANIZATION_ID   IN (203,204,328) 
AND BORV.COMMON_ROUTING_SEQUENCE_ID = WDJV.COMMON_ROUTING_SEQUENCE_ID 
AND BORV.ASSEMBLY_ITEM_ID = WDJV.PRIMARY_ITEM_ID 
AND WDJV.CREATION_DATE > ADD_MONTHS(sysdate, -12*3) 
AND WDJV.WIP_ENTITY_NAME = '28799' 
    --and MSI.SEGMENT1='9064090' 

另外,我已发现,5集合彼此不同其WE_ROW_ID,REQUEST_ID_7,SCHEDULED_START_DATE,SCHEDULED_COMPLETION_DATE并且其存在于WIP_DISCREET_JOBS表中的其它列的基础上。有没有办法将这些列映射到任何BOM表?我对此很陌生,所以请耐心等待我的大师们。

+0

请看[mcve]来改善你的问题。此外,旧的Oracle连接语法并不是一个好主意;考虑使用ANSI sql – Aleksej

+0

@Aleksej考虑到ANSI SQL不在我手中。我必须使用这个语法。 –

+0

@SoumyadeepPaul您仍然可以按照Aleksej的其他建议,从查询中删除不相关的表,连接,过滤器和选定的列,直到长度大概在10-15行而不是40个为止。大概所有这些外部连接的查找都不是导致问题呢?如果没有,请将其从查询中移除并重新发布。这将帮助我们帮助你! –

回答

2

我看到您在询问Oracle电子商务套件数据模型。

试图获取物品......并且其创建日期与过去三年一致。

这不是你的查询所做的事情。您可以在过去3年内获得有关物品的详细信息(通过WIP离散工作) - 并且每次制作时都会收到该物品的副本(即每次出现在WIP_DISCRETE_JOBS_V之内)。

如果您想要在过去3年内制作的物品,但您只希望每个物品一次,则应该使用EXISTS(半连接)来过滤行,而不是实际加入WIP_DISCRETE_JOBS_V,这会导致重复)。更多沿着这些方面的东西:

SELECT * 
FROM bom_bill_of_materials bom, 
     bom_inventory_components bic, 
     bom_components_b bcb, 
     bom_operational_routings_v borv, 
     bom_operation_sequences_v bosv, 
     bom_structures_b bsb, 
     bom_structure_types_b bst, 
     mtl_system_items_b msi, 
     mtl_system_items_tl msit, 
     org_organization_definitions ood --, 
     --wip_discrete_jobs_v wdjv 
WHERE bom.bill_sequence_id = bic.bill_sequence_id 
AND bic.component_sequence_id = bcb.component_sequence_id 
AND bcb.bill_sequence_id = bsb.bill_sequence_id 
AND bom.structure_type_id = bst.structure_type_id 
AND bom.assembly_item_id = msi.inventory_item_id 
AND bom.organization_id = msi.organization_id 
AND bosv.routing_sequence_id = borv.routing_sequence_id 
AND borv.assembly_item_id = bom.assembly_item_id 
AND borv.organization_id = bom.organization_id 
AND msi.inventory_item_id = msit.inventory_item_id 
AND msi.organization_id = msit.organization_id 
AND msit.organization_id = ood.organization_id 
AND msit.language = USERENV ('LANG') 
AND SYSDATE BETWEEN bcb.effectivity_date AND NVL (bcb.disable_date, SYSDATE) 
AND msi.bom_enabled_flag = 'Y' 
AND NVL (msi.enabled_flag, 'X') = 'Y' 
AND ood.organization_id IN (203, 204, 328) 
--AND borv.common_routing_sequence_id = wdjv.common_routing_sequence_id 
--AND borv.assembly_item_id = wdjv.primary_item_id 
--AND wdjv.creation_date > ADD_MONTHS (SYSDATE, -12 * 3) 
--AND wdjv.wip_entity_name = '28799' 
AND EXISTS (SELECT 'discrete job within the last 3 years' 
       FROM wip_discrete_jobs_v wdjv 
       WHERE wdjv.common_routing_sequence_id = borv.common_routing_sequence_id 
       AND wdjv.primary_item_id = borv.assembly_item_id 
       AND wdjv.creation_date >= ADD_MONTHS(SYSDATE, -12*3) 
       ) 
--and MSI.SEGMENT1='9064090' 

注 - 我保持这尽可能接近您的原始查询,我没有验证所有您使用的连接条件。因此,您的初始查询中可能存在一些其他错误,这些错误是我无意中复制的。

另一件事,使用窗体视图不是一个好习惯,如WIP_DISCRETE_JOBS_VBOM_OPERATIONAL_ROUTINGS_V。这些观点是为在线表单提供数据。不仅可以将您的性能遭受(因为它们包含联接,你可能不需要),但是,如果你去Oracle的ETRM网站(http://etrm.oracle.com/pls/etrm/etrm_pnav.show_object?c_name=BOM_OPERATIONAL_ROUTINGS_V&c_owner=APPS&c_type=VIEW),你会看到这样的警告:

警告:Oracle不建议您使用此 视图查询或更改数据。在随后的次要版本或主要版本中,它可能会发生显着变化。

最好从基表中删除SELECT

+0

您的查询完美无瑕。但你也提到“如果我只想每个项目一次,我应该使用EXISTS(半连接)来过滤行,而不是实际加入WIP_DISCRETE_JOBS_V。”你能再解释一下吗? 此外,我理解使用表单视图的长期影响,并已根据您的建议用基表替换视图表。再次感谢。 –

+0

我给你的查询是一个如何使用'EXISTS'/semi-join来过滤项目的例子。如果(通常是相关的)子查询返回任何行,'EXISTS'就是一个返回TRUE的表达式。请参阅https://docs.oracle.com/database/121/SQLRF/queries006.htm#SQLRF30046 –

+0

即使我获得唯一记录,但仍似乎无法获取每个项目的所有组件。我正尝试从BOM_INVENTORY_COMPONENTS中选择COMPONENT_ITEM_ID。我将此列加入了MTL_SYSTEM_ITEMS_B表的INVENTORY_ITEM_ID。它要么为每个项目返回空值或不完整的数据。 –