Finding a the Min value for a group, filtering out preceding min values based upon a less selective group












5














How do I get the minimum value for a group (Acc, TranType), but filtering out any minimum values used in preceding rows for the Acc group. Preceding rows would be defined as Acc asc, TranType asc



So with the given data set:



Acc  | TranType | PosCancelID
100 1 2
808 1 5
808 1 4
808 2 5
808 2 4<--To be filtered from min calc as it min for (808,1)
813 2 3
813 4 3<--To be filtered from min calc as it min for (813,2)


I should get:



Acc  | TranType | PosCancelID
100 1 2
808 1 4
808 2 5
813 2 3

SELECT ACC, TranType, min(maxPreceeding) as ActualCancelID
FROM
(
SELECT ACC, TranType,
MAX(m.posCancelID) OVER (PARTITION BY m.ACC
ORDER BY m.TranType, m.posCancelID
ROWS UNBOUNDED PRECEDING) as maxPreceeding
FROM MCancel as m
) AS x
GROUP BY ACC, TranType


The above query gives me almost what i want but isn't filtering for acc = 813. So I know there must be a better (actually applying a filter to remove previous minimum values) way.










share|improve this question




















  • 2




    Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
    – McNets
    4 hours ago
















5














How do I get the minimum value for a group (Acc, TranType), but filtering out any minimum values used in preceding rows for the Acc group. Preceding rows would be defined as Acc asc, TranType asc



So with the given data set:



Acc  | TranType | PosCancelID
100 1 2
808 1 5
808 1 4
808 2 5
808 2 4<--To be filtered from min calc as it min for (808,1)
813 2 3
813 4 3<--To be filtered from min calc as it min for (813,2)


I should get:



Acc  | TranType | PosCancelID
100 1 2
808 1 4
808 2 5
813 2 3

SELECT ACC, TranType, min(maxPreceeding) as ActualCancelID
FROM
(
SELECT ACC, TranType,
MAX(m.posCancelID) OVER (PARTITION BY m.ACC
ORDER BY m.TranType, m.posCancelID
ROWS UNBOUNDED PRECEDING) as maxPreceeding
FROM MCancel as m
) AS x
GROUP BY ACC, TranType


The above query gives me almost what i want but isn't filtering for acc = 813. So I know there must be a better (actually applying a filter to remove previous minimum values) way.










share|improve this question




















  • 2




    Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
    – McNets
    4 hours ago














5












5








5







How do I get the minimum value for a group (Acc, TranType), but filtering out any minimum values used in preceding rows for the Acc group. Preceding rows would be defined as Acc asc, TranType asc



So with the given data set:



Acc  | TranType | PosCancelID
100 1 2
808 1 5
808 1 4
808 2 5
808 2 4<--To be filtered from min calc as it min for (808,1)
813 2 3
813 4 3<--To be filtered from min calc as it min for (813,2)


I should get:



Acc  | TranType | PosCancelID
100 1 2
808 1 4
808 2 5
813 2 3

SELECT ACC, TranType, min(maxPreceeding) as ActualCancelID
FROM
(
SELECT ACC, TranType,
MAX(m.posCancelID) OVER (PARTITION BY m.ACC
ORDER BY m.TranType, m.posCancelID
ROWS UNBOUNDED PRECEDING) as maxPreceeding
FROM MCancel as m
) AS x
GROUP BY ACC, TranType


The above query gives me almost what i want but isn't filtering for acc = 813. So I know there must be a better (actually applying a filter to remove previous minimum values) way.










share|improve this question















How do I get the minimum value for a group (Acc, TranType), but filtering out any minimum values used in preceding rows for the Acc group. Preceding rows would be defined as Acc asc, TranType asc



So with the given data set:



Acc  | TranType | PosCancelID
100 1 2
808 1 5
808 1 4
808 2 5
808 2 4<--To be filtered from min calc as it min for (808,1)
813 2 3
813 4 3<--To be filtered from min calc as it min for (813,2)


I should get:



Acc  | TranType | PosCancelID
100 1 2
808 1 4
808 2 5
813 2 3

SELECT ACC, TranType, min(maxPreceeding) as ActualCancelID
FROM
(
SELECT ACC, TranType,
MAX(m.posCancelID) OVER (PARTITION BY m.ACC
ORDER BY m.TranType, m.posCancelID
ROWS UNBOUNDED PRECEDING) as maxPreceeding
FROM MCancel as m
) AS x
GROUP BY ACC, TranType


The above query gives me almost what i want but isn't filtering for acc = 813. So I know there must be a better (actually applying a filter to remove previous minimum values) way.







t-sql sql-server-2016






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 5 hours ago









McNets

14.4k41756




14.4k41756










asked 5 hours ago









I Donaldson

31114




31114








  • 2




    Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
    – McNets
    4 hours ago














  • 2




    Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
    – McNets
    4 hours ago








2




2




Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
– McNets
4 hours ago




Min values of one group cannot be the minimin value of the previous o cannot be the min of any other previous group?
– McNets
4 hours ago










2 Answers
2






active

oldest

votes


















2














Quite a hard problem. Here is a recursive solution:



WITH 
rcte AS
( SELECT TOP (1)
Acc, TranType, posCancelID,
CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
FROM
MCancel
ORDER BY
Acc, TranType

UNION ALL

SELECT
Acc, TranType, posCancelID,
CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
FROM
( SELECT
m.*,
r.IDs,
ROW_NUMBER() OVER (ORDER BY m.Acc, m. TranType, m.PosCancelID) AS rn
FROM
rcte AS r
JOIN MCancel AS m
ON (m.Acc = r.Acc AND m.TranType > r.TranType)
OR (m.Acc > r.Acc)
WHERE
r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
) AS mc
WHERE
rn = 1
)
SELECT Acc, TranType, posCancelID
FROM rcte
ORDER BY Acc, TranType ;


The solution assumes that a posCancelID should not appear twice in the result set. If the requirements are that they should not appear twice in the same Acc group, then the solution needs a slight adjustment:





WITH rcte AS
( SELECT
Acc, TranType, posCancelID,
CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
FROM
( SELECT
Acc, TranType, posCancelID,
ROW_NUMBER() OVER (PARTITION BY Acc ORDER BY TranType, PosCancelID) AS rnk
FROM MCancel
) AS f
WHERE rnk = 1

UNION ALL

SELECT
Acc, TranType, posCancelID,
CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
FROM
( SELECT
m.*, r.IDs,
ROW_NUMBER() OVER (PARTITION BY m.Acc
ORDER BY m.TranType, m.PosCancelID) AS rn
FROM
rcte AS r
JOIN MCancel AS m
ON (m.Acc = r.Acc AND m.TranType > r.TranType)
WHERE
r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
) AS mc
WHERE rn = 1
)
SELECT Acc, TranType, posCancelID
FROM rcte
ORDER BY Acc, TranType ;


Both are tested at dbfiddle.uk






share|improve this answer































    0














    First CTE simply calculates minimum PosCancelID of each group of (Acc, TranType).



    Second one, adds the minimum PosCancelID calculated of the previous group.



    And finally it calculates again the minimum PosCancelID, avoiding the minimum of the previous group. Note I've used t1.PosCancelID <> ct2.LastMin, maybe you need a solution where t1.PosCancelID > ct2.LastMin.



    WITH ct1 AS
    (
    SELECT
    Acc, TranType,
    MIN(PosCancelID)as MinP
    FROM
    MCancel
    GROUP BY
    Acc, TranType
    )
    , ct2 AS
    (
    SELECT
    Acc, TranType, MinP,
    COALESCE(LAG(MinP) OVER (ORDER BY Acc, TranType), 0) LastMin
    FROM
    ct1
    )
    SELECT
    t1.Acc, t1.TranType,
    MIN(PosCancelID) as MinP
    FROM
    MCancel t1
    JOIN
    ct2
    ON ct2.Acc = t1.Acc
    AND ct2.TranType = t1.TranType
    WHERE
    t1.PosCancelID <> ct2.LastMin
    GROUP BY
    t1.Acc, t1.TranType;



    Acc | TranType | MinP
    --: | -------: | ---:
    100 | 1 | 2
    808 | 1 | 4
    808 | 2 | 5
    813 | 2 | 3


    db<>fiddle here






    share|improve this answer























    • See the result of this: dbfiddle.uk/…
      – yper-crazyhat-cubeᵀᴹ
      1 hour ago











    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "182"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f225548%2ffinding-a-the-min-value-for-a-group-filtering-out-preceding-min-values-based-up%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    Quite a hard problem. Here is a recursive solution:



    WITH 
    rcte AS
    ( SELECT TOP (1)
    Acc, TranType, posCancelID,
    CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
    FROM
    MCancel
    ORDER BY
    Acc, TranType

    UNION ALL

    SELECT
    Acc, TranType, posCancelID,
    CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
    FROM
    ( SELECT
    m.*,
    r.IDs,
    ROW_NUMBER() OVER (ORDER BY m.Acc, m. TranType, m.PosCancelID) AS rn
    FROM
    rcte AS r
    JOIN MCancel AS m
    ON (m.Acc = r.Acc AND m.TranType > r.TranType)
    OR (m.Acc > r.Acc)
    WHERE
    r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
    ) AS mc
    WHERE
    rn = 1
    )
    SELECT Acc, TranType, posCancelID
    FROM rcte
    ORDER BY Acc, TranType ;


    The solution assumes that a posCancelID should not appear twice in the result set. If the requirements are that they should not appear twice in the same Acc group, then the solution needs a slight adjustment:





    WITH rcte AS
    ( SELECT
    Acc, TranType, posCancelID,
    CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
    FROM
    ( SELECT
    Acc, TranType, posCancelID,
    ROW_NUMBER() OVER (PARTITION BY Acc ORDER BY TranType, PosCancelID) AS rnk
    FROM MCancel
    ) AS f
    WHERE rnk = 1

    UNION ALL

    SELECT
    Acc, TranType, posCancelID,
    CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
    FROM
    ( SELECT
    m.*, r.IDs,
    ROW_NUMBER() OVER (PARTITION BY m.Acc
    ORDER BY m.TranType, m.PosCancelID) AS rn
    FROM
    rcte AS r
    JOIN MCancel AS m
    ON (m.Acc = r.Acc AND m.TranType > r.TranType)
    WHERE
    r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
    ) AS mc
    WHERE rn = 1
    )
    SELECT Acc, TranType, posCancelID
    FROM rcte
    ORDER BY Acc, TranType ;


    Both are tested at dbfiddle.uk






    share|improve this answer




























      2














      Quite a hard problem. Here is a recursive solution:



      WITH 
      rcte AS
      ( SELECT TOP (1)
      Acc, TranType, posCancelID,
      CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
      FROM
      MCancel
      ORDER BY
      Acc, TranType

      UNION ALL

      SELECT
      Acc, TranType, posCancelID,
      CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
      FROM
      ( SELECT
      m.*,
      r.IDs,
      ROW_NUMBER() OVER (ORDER BY m.Acc, m. TranType, m.PosCancelID) AS rn
      FROM
      rcte AS r
      JOIN MCancel AS m
      ON (m.Acc = r.Acc AND m.TranType > r.TranType)
      OR (m.Acc > r.Acc)
      WHERE
      r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
      ) AS mc
      WHERE
      rn = 1
      )
      SELECT Acc, TranType, posCancelID
      FROM rcte
      ORDER BY Acc, TranType ;


      The solution assumes that a posCancelID should not appear twice in the result set. If the requirements are that they should not appear twice in the same Acc group, then the solution needs a slight adjustment:





      WITH rcte AS
      ( SELECT
      Acc, TranType, posCancelID,
      CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
      FROM
      ( SELECT
      Acc, TranType, posCancelID,
      ROW_NUMBER() OVER (PARTITION BY Acc ORDER BY TranType, PosCancelID) AS rnk
      FROM MCancel
      ) AS f
      WHERE rnk = 1

      UNION ALL

      SELECT
      Acc, TranType, posCancelID,
      CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
      FROM
      ( SELECT
      m.*, r.IDs,
      ROW_NUMBER() OVER (PARTITION BY m.Acc
      ORDER BY m.TranType, m.PosCancelID) AS rn
      FROM
      rcte AS r
      JOIN MCancel AS m
      ON (m.Acc = r.Acc AND m.TranType > r.TranType)
      WHERE
      r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
      ) AS mc
      WHERE rn = 1
      )
      SELECT Acc, TranType, posCancelID
      FROM rcte
      ORDER BY Acc, TranType ;


      Both are tested at dbfiddle.uk






      share|improve this answer


























        2












        2








        2






        Quite a hard problem. Here is a recursive solution:



        WITH 
        rcte AS
        ( SELECT TOP (1)
        Acc, TranType, posCancelID,
        CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
        FROM
        MCancel
        ORDER BY
        Acc, TranType

        UNION ALL

        SELECT
        Acc, TranType, posCancelID,
        CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
        FROM
        ( SELECT
        m.*,
        r.IDs,
        ROW_NUMBER() OVER (ORDER BY m.Acc, m. TranType, m.PosCancelID) AS rn
        FROM
        rcte AS r
        JOIN MCancel AS m
        ON (m.Acc = r.Acc AND m.TranType > r.TranType)
        OR (m.Acc > r.Acc)
        WHERE
        r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
        ) AS mc
        WHERE
        rn = 1
        )
        SELECT Acc, TranType, posCancelID
        FROM rcte
        ORDER BY Acc, TranType ;


        The solution assumes that a posCancelID should not appear twice in the result set. If the requirements are that they should not appear twice in the same Acc group, then the solution needs a slight adjustment:





        WITH rcte AS
        ( SELECT
        Acc, TranType, posCancelID,
        CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
        FROM
        ( SELECT
        Acc, TranType, posCancelID,
        ROW_NUMBER() OVER (PARTITION BY Acc ORDER BY TranType, PosCancelID) AS rnk
        FROM MCancel
        ) AS f
        WHERE rnk = 1

        UNION ALL

        SELECT
        Acc, TranType, posCancelID,
        CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
        FROM
        ( SELECT
        m.*, r.IDs,
        ROW_NUMBER() OVER (PARTITION BY m.Acc
        ORDER BY m.TranType, m.PosCancelID) AS rn
        FROM
        rcte AS r
        JOIN MCancel AS m
        ON (m.Acc = r.Acc AND m.TranType > r.TranType)
        WHERE
        r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
        ) AS mc
        WHERE rn = 1
        )
        SELECT Acc, TranType, posCancelID
        FROM rcte
        ORDER BY Acc, TranType ;


        Both are tested at dbfiddle.uk






        share|improve this answer














        Quite a hard problem. Here is a recursive solution:



        WITH 
        rcte AS
        ( SELECT TOP (1)
        Acc, TranType, posCancelID,
        CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
        FROM
        MCancel
        ORDER BY
        Acc, TranType

        UNION ALL

        SELECT
        Acc, TranType, posCancelID,
        CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
        FROM
        ( SELECT
        m.*,
        r.IDs,
        ROW_NUMBER() OVER (ORDER BY m.Acc, m. TranType, m.PosCancelID) AS rn
        FROM
        rcte AS r
        JOIN MCancel AS m
        ON (m.Acc = r.Acc AND m.TranType > r.TranType)
        OR (m.Acc > r.Acc)
        WHERE
        r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
        ) AS mc
        WHERE
        rn = 1
        )
        SELECT Acc, TranType, posCancelID
        FROM rcte
        ORDER BY Acc, TranType ;


        The solution assumes that a posCancelID should not appear twice in the result set. If the requirements are that they should not appear twice in the same Acc group, then the solution needs a slight adjustment:





        WITH rcte AS
        ( SELECT
        Acc, TranType, posCancelID,
        CAST('=' + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX)) AS IDs
        FROM
        ( SELECT
        Acc, TranType, posCancelID,
        ROW_NUMBER() OVER (PARTITION BY Acc ORDER BY TranType, PosCancelID) AS rnk
        FROM MCancel
        ) AS f
        WHERE rnk = 1

        UNION ALL

        SELECT
        Acc, TranType, posCancelID,
        CAST(IDs + CAST(posCancelID AS VARCHAR(20)) + '=' AS VARCHAR(MAX))
        FROM
        ( SELECT
        m.*, r.IDs,
        ROW_NUMBER() OVER (PARTITION BY m.Acc
        ORDER BY m.TranType, m.PosCancelID) AS rn
        FROM
        rcte AS r
        JOIN MCancel AS m
        ON (m.Acc = r.Acc AND m.TranType > r.TranType)
        WHERE
        r.IDs NOT LIKE ('%=' + CAST(m.posCancelID AS VARCHAR(20)) + '=%')
        ) AS mc
        WHERE rn = 1
        )
        SELECT Acc, TranType, posCancelID
        FROM rcte
        ORDER BY Acc, TranType ;


        Both are tested at dbfiddle.uk







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 41 mins ago

























        answered 1 hour ago









        yper-crazyhat-cubeᵀᴹ

        74.3k11125206




        74.3k11125206

























            0














            First CTE simply calculates minimum PosCancelID of each group of (Acc, TranType).



            Second one, adds the minimum PosCancelID calculated of the previous group.



            And finally it calculates again the minimum PosCancelID, avoiding the minimum of the previous group. Note I've used t1.PosCancelID <> ct2.LastMin, maybe you need a solution where t1.PosCancelID > ct2.LastMin.



            WITH ct1 AS
            (
            SELECT
            Acc, TranType,
            MIN(PosCancelID)as MinP
            FROM
            MCancel
            GROUP BY
            Acc, TranType
            )
            , ct2 AS
            (
            SELECT
            Acc, TranType, MinP,
            COALESCE(LAG(MinP) OVER (ORDER BY Acc, TranType), 0) LastMin
            FROM
            ct1
            )
            SELECT
            t1.Acc, t1.TranType,
            MIN(PosCancelID) as MinP
            FROM
            MCancel t1
            JOIN
            ct2
            ON ct2.Acc = t1.Acc
            AND ct2.TranType = t1.TranType
            WHERE
            t1.PosCancelID <> ct2.LastMin
            GROUP BY
            t1.Acc, t1.TranType;



            Acc | TranType | MinP
            --: | -------: | ---:
            100 | 1 | 2
            808 | 1 | 4
            808 | 2 | 5
            813 | 2 | 3


            db<>fiddle here






            share|improve this answer























            • See the result of this: dbfiddle.uk/…
              – yper-crazyhat-cubeᵀᴹ
              1 hour ago
















            0














            First CTE simply calculates minimum PosCancelID of each group of (Acc, TranType).



            Second one, adds the minimum PosCancelID calculated of the previous group.



            And finally it calculates again the minimum PosCancelID, avoiding the minimum of the previous group. Note I've used t1.PosCancelID <> ct2.LastMin, maybe you need a solution where t1.PosCancelID > ct2.LastMin.



            WITH ct1 AS
            (
            SELECT
            Acc, TranType,
            MIN(PosCancelID)as MinP
            FROM
            MCancel
            GROUP BY
            Acc, TranType
            )
            , ct2 AS
            (
            SELECT
            Acc, TranType, MinP,
            COALESCE(LAG(MinP) OVER (ORDER BY Acc, TranType), 0) LastMin
            FROM
            ct1
            )
            SELECT
            t1.Acc, t1.TranType,
            MIN(PosCancelID) as MinP
            FROM
            MCancel t1
            JOIN
            ct2
            ON ct2.Acc = t1.Acc
            AND ct2.TranType = t1.TranType
            WHERE
            t1.PosCancelID <> ct2.LastMin
            GROUP BY
            t1.Acc, t1.TranType;



            Acc | TranType | MinP
            --: | -------: | ---:
            100 | 1 | 2
            808 | 1 | 4
            808 | 2 | 5
            813 | 2 | 3


            db<>fiddle here






            share|improve this answer























            • See the result of this: dbfiddle.uk/…
              – yper-crazyhat-cubeᵀᴹ
              1 hour ago














            0












            0








            0






            First CTE simply calculates minimum PosCancelID of each group of (Acc, TranType).



            Second one, adds the minimum PosCancelID calculated of the previous group.



            And finally it calculates again the minimum PosCancelID, avoiding the minimum of the previous group. Note I've used t1.PosCancelID <> ct2.LastMin, maybe you need a solution where t1.PosCancelID > ct2.LastMin.



            WITH ct1 AS
            (
            SELECT
            Acc, TranType,
            MIN(PosCancelID)as MinP
            FROM
            MCancel
            GROUP BY
            Acc, TranType
            )
            , ct2 AS
            (
            SELECT
            Acc, TranType, MinP,
            COALESCE(LAG(MinP) OVER (ORDER BY Acc, TranType), 0) LastMin
            FROM
            ct1
            )
            SELECT
            t1.Acc, t1.TranType,
            MIN(PosCancelID) as MinP
            FROM
            MCancel t1
            JOIN
            ct2
            ON ct2.Acc = t1.Acc
            AND ct2.TranType = t1.TranType
            WHERE
            t1.PosCancelID <> ct2.LastMin
            GROUP BY
            t1.Acc, t1.TranType;



            Acc | TranType | MinP
            --: | -------: | ---:
            100 | 1 | 2
            808 | 1 | 4
            808 | 2 | 5
            813 | 2 | 3


            db<>fiddle here






            share|improve this answer














            First CTE simply calculates minimum PosCancelID of each group of (Acc, TranType).



            Second one, adds the minimum PosCancelID calculated of the previous group.



            And finally it calculates again the minimum PosCancelID, avoiding the minimum of the previous group. Note I've used t1.PosCancelID <> ct2.LastMin, maybe you need a solution where t1.PosCancelID > ct2.LastMin.



            WITH ct1 AS
            (
            SELECT
            Acc, TranType,
            MIN(PosCancelID)as MinP
            FROM
            MCancel
            GROUP BY
            Acc, TranType
            )
            , ct2 AS
            (
            SELECT
            Acc, TranType, MinP,
            COALESCE(LAG(MinP) OVER (ORDER BY Acc, TranType), 0) LastMin
            FROM
            ct1
            )
            SELECT
            t1.Acc, t1.TranType,
            MIN(PosCancelID) as MinP
            FROM
            MCancel t1
            JOIN
            ct2
            ON ct2.Acc = t1.Acc
            AND ct2.TranType = t1.TranType
            WHERE
            t1.PosCancelID <> ct2.LastMin
            GROUP BY
            t1.Acc, t1.TranType;



            Acc | TranType | MinP
            --: | -------: | ---:
            100 | 1 | 2
            808 | 1 | 4
            808 | 2 | 5
            813 | 2 | 3


            db<>fiddle here







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 28 mins ago

























            answered 1 hour ago









            McNets

            14.4k41756




            14.4k41756












            • See the result of this: dbfiddle.uk/…
              – yper-crazyhat-cubeᵀᴹ
              1 hour ago


















            • See the result of this: dbfiddle.uk/…
              – yper-crazyhat-cubeᵀᴹ
              1 hour ago
















            See the result of this: dbfiddle.uk/…
            – yper-crazyhat-cubeᵀᴹ
            1 hour ago




            See the result of this: dbfiddle.uk/…
            – yper-crazyhat-cubeᵀᴹ
            1 hour ago


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Database Administrators Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f225548%2ffinding-a-the-min-value-for-a-group-filtering-out-preceding-min-values-based-up%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'