2016-09-22 113 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。它要麼爲每個項目返回空值或不完整的數據。 –