Progress OpenEdge 10.2B中的聚合函数

时间:2014-01-23 16:44:52

标签: progress-4gl

我的任务是将存储过程从SQL Server转换为Progress代码。

一切进展顺利但我昨天面临一个谜。

我们如何在Progress OpenEdge V10.2B中进行Min,Max,Avg等聚合功能?

这是一个SQL Server场景:

WITH Inventory (ItemNo, Quantity)
AS
(
          SELECT 'ItemA', 100
    UNION SELECT 'ItemA', 200
    UNION SELECT 'ItemC', 300
    UNION SELECT 'ItemB', 400
    UNION SELECT 'ItemA', 500
    UNION SELECT 'ItemB', 600
)
SELECT
    ItemNo
    ,MIN(Quantity)   AS Min1
    ,MAX(Quantity)   AS Max1
    ,AVG(Quantity)   AS Avg1
    ,SUM(Quantity)   AS Sum1
    ,COUNT(Quantity) AS Count1
FROM Inventory
GROUP BY
    ItemNo

结果是:

ItemNo   Min1    Max1    Avg1    Sum1     Count1
ItemA    100     500     266     800      3
ItemB    400     600     500     1000     2
ItemC    300     300     300     300      1

谢谢你, 祝你有美好的一天! 的Sebastien

2 个答案:

答案 0 :(得分:2)

这将为您提供ItemNo所需的值:

    DEFINE VARIABLE iMin    AS INTEGER      NO-UNDO.
    DEFINE VARIABLE iMax    AS INTEGER      NO-UNDO.
    DEFINE VARIABLE iTotal  AS INTEGER      NO-UNDO.
    DEFINE VARIABLE iCount  AS INTEGER      NO-UNDO.


    FOR EACH Inventory
        NO-LOCK
        BREAK BY Inventory.itemno
        :

        IF FIRST-OF(Inventory.itemno) THEN
            ASSIGN
                iMin    = 99999999
                iMax    = -99999999
                iTotal  = 0
                iCount  = 0
                .

        ASSIGN
            iMin    = MIN(iMin, inventory.quantity)
            iMax    = MAX(iMax, inventory.quantity)
            iTotal  = iTotal + inventory.quantity 
            iCount  = iCount + 1
            .

        IF LAST-OF(Inventory.itemno) THEN
            DISPLAY
                    Inventory.itemno
                    iMin
                    iMax
                    iTotal / iCount
                    iTotal
                    iCount
                WITH FRAME f-show
                    DOWN
                    .

    END.

答案 1 :(得分:2)

好的,我喜欢挑战。所以,这是使用Progress的内置聚合函数的解决方案。

首先,一些内务管理:设置临时表并填写它:

DEFINE TEMP-TABLE ttTest
    FIELD ItemNo AS CHARACTER
    FIELD Quantity AS INTEGER
    INDEX ItemNo ItemNo.

RUN ipCreateTest("ItemA",100).
RUN ipCreateTest("ItemA",200).
RUN ipCreateTest("ItemC",300).
RUN ipCreateTest("ItemB",400).
RUN ipCreateTest("ItemA",500).
RUN ipCreateTest("ItemB",600).

PROCEDURE ipCreateTest:
DEFINE INPUT  PARAMETER pcItem AS CHARACTER   NO-UNDO.
DEFINE INPUT  PARAMETER piQty  AS INTEGER     NO-UNDO.

CREATE ttTest.
ASSIGN
    ttTest.ItemNo = pcItem
    ttTest.Quantity = piQty
    .
END.

然后,实际报告部分:

FOR EACH ttTest
    NO-LOCK
    BREAK BY ttTest.ItemNo:
    ACCUMULATE ttTest.Quantity
        (MINIMUM MAXIMUM AVERAGE TOTAL COUNT BY ttTest.Itemno).
    IF LAST-OF(ttTest.itemNo) THEN DO:
        DISPLAY
            ttTest.ItemNo
            ACCUM MINIMUM BY ttTest.ItemNo ttTest.Quantity
                COLUMN-LABEL "Min1"
            ACCUM MAXIMUM BY ttTest.ItemNo ttTest.Quantity
                COLUMN-LABEL "Max1"
            ACCUM AVERAGE BY ttTest.ItemNo ttTest.Quantity
                COLUMN-LABEL "Avg1"
            ACCUM TOTAL BY ttTest.ItemNo ttTest.Quantity
                COLUMN-LABEL "Sum1"
            ACCUM COUNT BY ttTest.ItemNo ttTest.Quantity
                COLUMN-LABEL "Count1"
            .
    END.
END.

内置函数可以工作,但语法很反直觉恕我直言。我会选择蒂姆的解决方案,主要是因为我可能已经完成了该策略的问题,我花了很长时间才进入ACCUM和ACCUMULATE的第二次迭代,找出括号的位置......:)