1

我有以下表格:预订、订单行、订单页眉、产品、客户。对这些表中的每一个进行一些解释:

  • Reservations包含计费客户/产品组合的“保留”。
  • Order-Lines包含订单的行项目详细信息,包括他们订购的产品和数量。
  • Order-Header包含订单的标题信息,包括日期、客户和计费客户
  • 产品包含产品详细信息
  • 客户包含客户详细信息。

以下是带有相关字段和示例数据的表格:

Reservation
bill-cust-key  prod-key  qty-reserved  reserve-date
10000          20000     10            05/30/2014
10003          20000     5             06/20/2014
10003          20001     15            06/20/2014
10003          20001     5             06/25/2014
10002          20001     5             06/21/2014
10002          20002     20            06/21/2014

Order-Item
order-num   cust-key    prod-key    qty-ordered
30000       10000       20000       10
30000       10000       20001       5
30001       10001       20001       10
30002       10001       20001       5
30003       10002       20003       20

Order-Header
order-num   cust-key    bill-cust-key   order-date
30000       10000       10000           07/01/2014
30001       10001       10003           07/03/2014
30002       10001       10003           07/15/2014
30003       10002       10002           07/20/2014

Customer
cust-key    cust-name
10000       Customer A
10001       Customer B
10002       Customer C
10003       Customer D

Product
prod-key    prod-name
20000       Prod A
20001       Prod B
20002       Prod C
20003       Prod D

我正在尝试编写一个查询,该查询将向我显示预订和订单项表中存在的客户/产品组合。一个小麻烦是我们有一个客户和一个计费客户。保留和订单标题表都包含客户,但订单项目表只包含客户。结果应显示计费客户。此外,同一个客户/产品组合可以有多个预订和订购项目,所以我想显示 qty-reserved 和 qty-ordered 的总和。

下面是我想要的输出的一个例子:

bill-cust-key   cust-name   prod-key    prod-name   qty-ordered qty-reserved
10000           Customer A  20000       Prod A      10          10
10003           Customer D  20001       Prod B      15          20

这是我尝试过的查询,似乎对我不起作用。

SELECT customer.cust-key, customer.cust-name, product.prod-key, prod.prod-name,
     SUM(order-item.qty-ordered), SUM(reservation.qty-reserved)
FROM ((reservation INNER JOIN order-item on reservation.prod-key = order-item.product-key)
     INNER JOIN order-header on reservation.bill-cust-key = order-header.bill-cust-key and    
     order-item.order-num = order-header.order-num), customer, product
WHERE customer.cust-key = reservation.bill-cust-key
AND product.prod-key = reservation.prod-key
GROUP BY customer.cust-key, customer.cust-name, product.prod-key, product.prod-name

我很抱歉这么长的帖子!我只是想确保我的基地被覆盖!

4

3 回答 3

2

你想像这样加入你的表:

from reservation res join order-header oh on res.bill-cust-key = oh.bill-cust-key
join order-item oi on oi.order-num = oh.order-num
and oi.prod-key = res.prod-key
/*   join customer c on c.cust-key = oi.cust-key  old one */
join customer c on c.cust-key = oh.bill-cust-key
join product p on p.prod-key = oi.prod-key
于 2014-07-29T15:05:47.960 回答
1

我发现使用 CROSS APPLY(或 OUTER APPLY)将输出行与聚合行分开会非常有帮助,如果您无权访问这些查询,则只需使用别名内部查询。

例如,

SELECT 
    customer.cust-key, 
    customer.cust-name, 

    tDetails.prod-key, 
    tDetails.prod-name,
    tDetails.qty-ordered,
    tDetails.qty-reserved

FROM customer

--note that this could be an inner-select table in which you join if not cross-join
CROSS APPLY (
    SELECT
         product.prod-key, 
        prod.prod-name,
        SUM(order-item.qty-ordered) as qty-ordered, 
        SUM(reservation.qty-reserved) as qty-reserved
    FROM reservation
        INNER JOIN order-item ON reservation.prod-key = order-item.product-key
         INNER JOIN product ON reservation.prod-key = product.prod-key
    WHERE
        reservation.bill-cust-key = customer.cut-key
    GROUP BY product.prod-key, prod.prod-name
) tDetails

有很多方法可以对此进行分割,但是您以正确的方式开始说“我想要返回什么记录集”。我喜欢上面的内容,因为它可以帮助我想象每个“查询”在做什么。由 CROSS 应用标记的内部查询只是按产品订单和预订进行分组,但在外部最顶层查询中按当前客户进行过滤。

此外,我会将连接排除在“WHERE”子句之外。使用 'WHERE' 子句进行非主键过滤(例如 cust-name = 'Bob')。我发现说一个是表连接很有帮助,“WHERE”子句是一个属性过滤器。

TAKE 2 - 使用内联查询

这种方法仍然尝试获取具有不同产品的客户列表,然后使用该数据形成外部查询,您可以从中获取聚合。

SELECT 
    customer.cust-key, 
    customer.cust-name, 

    products.prod-key, 
    products.prod-name,

    --aggregate for orders
    (   SELECT SUM(order-item.qty-ordered) 
        FROM order-item 
        WHERE
            order-item.cust-key = customer.cust-key AND
            order-item.prod-key = products.prod-key) AS qty-ordered,

    --aggregate for reservations
    (   SELECT SUM(reservation.qty-reserved)
        FROM reservations
            --join up billingcustomers if they are different from customers here
        WHERE
            reservations.bill-cust-key = customer.cust-key AND
            reservations.prod-key = products.prod-key) AS qty-reserved

FROM customer

    --get a table of distinct products across orders and reservations
    --join products table for name
    CROSS JOIN (
        SELECT DISTINCT order-item.prod-key FROM order-item
        UNION
        SELECT DISTINCT reservation.prod-key FROM reservations
    ) tDistinctProducts
        INNER JOIN products ON products.prod-key = tDistinctProducts.prod-key

TAKE 3 - 派生表

根据一些快速谷歌搜索,Progress DB 确实支持派生表。这种方法在很大程度上已被 CROSS APPLY(或 OUTER APPLY)取代,因为您不需要进行分组。但是,如果您的数据库只支持这种方式,那就这样吧。

SELECT 
        customer.cust-key, 
        customer.cust-name, 

    products.prod-key, 
    products.prod-name,

   tOrderItems.SumQtyOrdered,

   tReservations.SumQtyReserved

FROM customer

    --get a table of distinct products across orders and reservations
    --join products table for name
    CROSS JOIN (
        SELECT DISTINCT order-item.prod-key FROM order-item
        UNION
        SELECT DISTINCT reservation.prod-key FROM reservations
    ) tDistinctProducts
        INNER JOIN products ON products.prod-key = tDistinctProducts.prod-key

    --derived table for order-items
    LEFT OUTER JOIN  (   SELECT 
                            order-item.cust-key,
                            order-item.prod-key,
                            SUM(order-item.qty-ordered) AS SumQtyOrdered
                        FROM order-item 
                        GROUP BY 
                            order-item.cust-key,
                            order-item.prod-key) tOrderItems ON
                                    tOrderItems.cust-key = customer.cust-key AND
                                    tOrderItems.prod-key = products.prod-key

    --derived table for reservations
    LEFT OUTER JOIN (   SELECT
                            reservations.bill-cust-key,
                            reservations.prod-key,
                            SUM(reservations.qty-reserved) AS SumQtyReserved
                        FROM reservations
                            --join up billingcustomers if they are different from customers here
                        WHERE
                            reservations.bill-cust-key = customer.cust-key AND
                            reservations.prod-key = products.prod-key) tReservations ON
                                tReservations.bill-cust-key = customer.cust-key AND
                                tReservations.prod-key = products.prod-key
于 2014-07-29T15:27:19.313 回答
1

根据您的原始代码和请求,这里是 Progress 解决方案的起点 -

DEFINE VARIABLE iQtyOrd         AS INTEGER     NO-UNDO.
DEFINE VARIABLE iQtyReserved    AS INTEGER     NO-UNDO.

FOR EACH order-item
    NO-LOCK,

    EACH order-header
        WHERE order-header.order-num = order-item.order-num
        NO-LOCK,

    EACH reservation
        WHERE reservation.prod-key      = order-item.prod-key    AND
              reservation.bill-cust-key = order-header.bill-cust-key
        NO-LOCK,

    EACH product
        WHERE product.prod-key = reservation.prod-key
        NO-LOCK,

    EACH customer
        WHERE customer.cust-key = reservation.bill-cust-key
        NO-LOCK

    BREAK BY customer.cust-key
          BY product.prod-key
          BY product.prod-name
    :

    IF FIRST-OF(customer.cust-key) OR FIRST-OF(product.prod-key) THEN
        ASSIGN
            iQtyOrd = 0
            iQtyReserved = 0
            .

    ASSIGN
        iQtyOrd         = iQtyOrd + reservation.qty-ordered
        iQtyReserved    = iQtyReserved + reservation.qty-reserved
        .

    IF LAST-OF(customer.cust-key) OR LAST-OF(product.prod-key) THEN
        DISPLAY
                customer.cust-key
                customer.cust-name
                product.prod-key
                prod.prod-name
                iQtyOrd
                iQtyReserved
            WITH FRAME f-qty
                DOWN
                .

END.
于 2014-07-30T14:41:52.493 回答