创建递归SQL语句,计算总数量

时间:2012-05-08 08:54:47

标签: sql oracle tree oracle11g recursive-query

我无法找到问题的解决方案。我有4张桌子:

BomModule:此表代表数据库中的模块。

CREATE TABLE "BOMMODULE"
(
    "MODULEID" NUMBER(10,0) NOT NULL ENABLE,
    "ISROOTMODULE"     NUMBER(1,0) NOT NULL ENABLE,
    "MODULENAME"       VARCHAR2(255 CHAR),
    ...
)

BomItem:此表表示一个叶子 - 或数据库中的项目。

CREATE TABLE "BOMITEM"
(
    "ITEMID"     NUMBER(10,0) NOT NULL ENABLE,
    ...
)

ModuleConnection:此表将模块映射到另一个父模块。您可以定义属于特定父模块的子模块的数量。

CREATE TABLE "MODULECONNECTION"
(
    "ID"       NUMBER(10,0) NOT NULL ENABLE,
    "QUANTITY"   NUMBER(10,0) NOT NULL ENABLE,
    "SUBMODULE_MODULEID"   NUMBER(10,0) NOT NULL ENABLE,
    "PARENTMODULE_MODULEID" NUMBER(10,0) NOT NULL ENABLE,
    ...
)

ItemModuleConnection: 此表将所有假项映射到模块。此外,您可以定义一个模块的项目数量。

CREATE TABLE "ITEMMODULECONNECTION"
(
    "ID"       NUMBER(10,0) NOT NULL ENABLE,
    "QUANTITY" NUMBER(10,0) NOT NULL ENABLE,
    "ITEMID"   NUMBER(10,0),
    "MODULEID" NUMBER(10,0),
    ...
)

从表结构中可以看出,项目和模块彼此连接并具有不同的数量。由于这些连接非常灵活,我无法创建一个SQL语句,它将为我提供项目的总数量:

select quantity from ...... where itemId = xy;

SQL语句应该检查项目中的所有数量到根模块并将它们相乘:

2 x rootmodule (total 2)
-- 1x submodule 1 (total 2)
-- 2x submodule 2 (total 4)
---- 5x item 1 (total 20)
---- 6x item 2 (total 24)

请帮我创建这个sql语句,非常感谢你的回答!

约束:
- 它必须是一个SQL语句(它在Java应用程序中使用)
- 数据库是Oracle 11g

2 个答案:

答案 0 :(得分:0)

您需要的是oracle的connect bystart with子句。抱歉没时间实际提出一个sql语句,但语法在这里解释:http://www.adp-gmbh.ch/ora/sql/connect_by.html

答案 1 :(得分:0)

我能够通过使用Java而不是SQL来解决这个问题。这是我的方法:

/**
 * This recursive functions interates through the whole tree and checks if there are items and modules.
 * As soon as an item is found, it is multiplied with the module amount. The result is saved in a HashMap. 
 * This HashMap is being parsed in the end.
 */
public HashMap<Integer, Integer> updateBom(HashMap<Integer, Integer> bom, BomModule module, int amount, BomHandling bh) {
    if(bom == null) {
        bom = new HashMap<Integer, Integer>();
    }
    // get all items for this parent module
    Collection<ItemModuleConnection> items = bh.getItems(module.getModuleId());
    Iterator<ItemModuleConnection> itemIterator = items.iterator();

    while(itemIterator.hasNext()) {
        ItemModuleConnection con = itemIterator.next();

        int itemQuantity = con.getQuantity() * amount;

        // if bom item already exists in bom list, get it and update quantity
        Integer currentItemQuantity = new Integer(0);
        if(bom.containsKey(new Integer(con.getItem().getItemId()))) {
            currentItemQuantity = bom.get(con.getItem().getItemId());
            bom.remove(bom.get(con.getItem().getItemId()));
        }
        bom.put(con.getItem().getItemId(), currentItemQuantity + itemQuantity);
    }

    // get all modules for this parent module
    Collection<ModuleConnection> modules = bh.getConnections(module.getModuleId());
    Iterator<ModuleConnection> moduleIterator = modules.iterator();

    // set the quantity of the module by multiplying it with the amount
    while(moduleIterator.hasNext()) {
        ModuleConnection moduleCon = moduleIterator.next();
        int moduleQuantity = moduleCon.getQuantity();
        updateBom(bom, moduleCon.getSubModule(), moduleQuantity * amount, bh);
    }
    return bom;
}

在打印单个Items之前,我调用此updateBom() - 函数,然后从HashMap中检索值:

HashMap<Integer, Integer> bom = updateBom(null, bomModule, 1, bh);
Iterator<Map.Entry<Integer, Integer>> entries = bom.entrySet().iterator();

while (entries.hasNext()) {

    Map.Entry<Integer, Integer> bomEntry = entries.next();
    BomItem item = bh.getBomItem(bomEntry.getKey());
    Integer itemAmount = bomEntry.getValue();

    ...
}