【问题标题】:Oracle making one to one joinOracle 进行一对一连接
【发布时间】:2021-12-11 12:35:36
【问题描述】:

我想从多对多进行一对多连接。两个表格示例:

生产:

ORDER PRODUCED_AMOUNT PRODUCT_ID
Order1 1000 ProductID1
Order1 1000 ProductID1
Order1 5000 ProductID2

订单:

ORDER AMOUNT_TO_PRODUCE PRODUCT PRODUCT_ID
Order1 600 Product1 - note1 ProductID1
Order1 600 Product1 - note2 ProductID1
Order1 600 Product1 - note3 ProductID1
Order1 5000 Product2 ProductID2

如果我编写一个示例查询,例如

SELECT ORDERS.ORDER, ORDER.AMOUNT_TO_PRODUCE, SUM(PRODUCTION.PRODUCED_AMOUNT), ORDERS.PRODUCT
FROM ORDERS JOIN PRODUCTION ON ORDERS.PRODUCT_ID = PRODUCTION.PRODUCT_ID
GROUP BY ORDERS.ORDER, ORDER.AMOUNT_TO_PRODUCE, ORDERS.PRODUCT

我明白了

ORDER AMOUNT_TO_PRODUCE PRODUCED_AMOUNT PRODUCT
Order1 600 2000 Product1 - note1
Order1 600 2000 Product1 - note2
Order1 600 2000 Product1 - note3
Order1 5000 5000 Product2

但我想要

ORDER AMOUNT_TO_PRODUCE PRODUCED_AMOUNT PRODUCT
Order1 600 2000 Product1 - note1
Order1 600 0 Product1 - note2
Order1 600 0 Product1 - note3
Order1 5000 5000 Product2

【问题讨论】:

    标签: oracle join oracle11g


    【解决方案1】:

    您似乎想要查找生产的总数量并将其连接到订单表中每个订单和产品 ID 的第一行。如果是这种情况,您应该:

    1. 在加入生产行之前对它们求和
    2. 根据订单和产品 ID 确定订单表中的第一行,您可以使用 row_number() 分析函数来完成此操作
    3. 将两者连接在一起,这将涉及到订单表的总和生产行的外部连接

    你可以这样做:

    WITH production AS (SELECT 'Order1' order_num, 1000 produced_amount, 'ProductID1' product_id FROM dual UNION ALL
                        SELECT 'Order1' order_num, 1000 produced_amount, 'ProductID1' product_id FROM dual UNION ALL
                        SELECT 'Order1' order_num, 5000 produced_amount, 'ProductID2' product_id FROM dual),
             orders AS (SELECT 'Order1' order_num, 600 amount_to_produce, 'Product1 - note1' product, 'ProductID1' product_id FROM dual UNION ALL
                        SELECT 'Order1' order_num, 600 amount_to_produce, 'Product1 - note2' product, 'ProductID1' product_id FROM dual UNION ALL
                        SELECT 'Order1' order_num, 600 amount_to_produce, 'Product1 - note3' product, 'ProductID1' product_id FROM dual UNION ALL
                        SELECT 'Order1' order_num, 5000 amount_to_produce, 'Product2' product, 'ProductID2' product_id FROM dual),
        -- end of mimicking your tables; main query below
        prdctn_amts AS (SELECT order_num,
                               SUM(produced_amount) total_produced_amount,
                               product_id
                        FROM   production
                        GROUP BY order_num,
                                 product_id),
         order_dets AS (SELECT order_num,
                               amount_to_produce,
                               product,
                               product_id,
                               row_number () OVER (PARTITION BY order_num, product_id ORDER BY product) rn
                        FROM   orders)
    SELECT o.order_num,
           o.amount_to_produce,
           NVL(p.total_produced_amount, 0)
           total_produced_amount,
           o.product
    FROM   order_dets o
           LEFT OUTER JOIN prdctn_amts p ON o.order_num = p.order_num
                                            AND o.product_id = p.product_id
                                            AND o.rn = 1
    ORDER BY o.order_num,
             o.product_id,
             o.rn;
    

    产生以下输出:

    ORDER_NUM AMOUNT_TO_PRODUCE TOTAL_PRODUCED_AMOUNT PRODUCT
    --------- ----------------- --------------------- ----------------
    Order1                  600                  2000 Product1 - note1
    Order1                  600                     0 Product1 - note2
    Order1                  600                     0 Product1 - note3
    Order1                 5000                  5000 Product2
    

    注意您不需要 with 子句中的前两个子查询;我已经添加了它们,所以我可以模仿你的两个表,而你只需要直接引用这两个表。另外,由于ORDER 是Oracle 中的保留字,我避免了每次需要通过将列名更改为ORDER_NUM 来引用它时都必须使用" 来封装列名。

    【讨论】:

    • 模仿表到底有什么作用?是必需的吗?我想我需要类似的方法。谢谢!
    • 我的数据库中没有您的表。我没有在我的数据库上创建表并将数据插入其中,而是简单地使用两个子查询来充当包含数据的表。这使我(和其他任何人)无需进行任何设置即可运行查询。你不需要使用这两个子查询,因为你已经有了实际的表,所以你可以从我的查询中删除它们。
    • 哦,对不起。我没有正确阅读最后一段。我想知道为什么很多人在答案中使用它。太棒了!
    猜你喜欢
    • 2022-06-15
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多