【问题标题】:Create recursive SQL statement that calculates total number of quantities创建计算总数量的递归 SQL 语句
【发布时间】:2012-05-08 08:54:47
【问题描述】:

我无法为我的问题找到解决方案。我有 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

【问题讨论】:

  • 我直接用 Java (Collections) 进行了尝试,但这使用了很多资源。不幸的是,我不知道如何在 SQL 中使用递归。
  • 您发布的表格中存在剪切粘贴错误。我试图修复它,但我不确定它是否正确。请检查
  • 这有多递归?子模块可以作为其他模块的父模块吗?另外,你能保证连接的完整性吗?循环(PM->SM1、SM1->SM2、SM2->PM)是一个 PITN。多条路径(PM1->SM1,PM2->SM1)或短路(PM->SM1,SM1->SM2,PM->SM2)也是如此。
  • 模块的数量是如何确定的?似乎数量是连接而不是模块的属性。在您展示的示例中,我看不出如何有两个“根模块”和一个“子模块 1”。我在这里错过了什么吗?
  • @APC,是的,子模块可以充当父模块,完整性由程序逻辑保证,不能添加循环(当然,在数据库级别上是可以的)。跨度>

标签: sql oracle tree oracle11g recursive-query


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我能够通过使用 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;
    }
    

    在打印单个项目之前,我调用了这个 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();
    
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-30
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多