Legend
Legend

Reputation: 116820

How do I approach this without using CURSORS or scripting language?

I have a vague idea of how to do this using CURSORs but am still trying to spend some time thinking about how to do this without using them. I have a table like this:

CREATE TABLE #MATCHEDADDITION(GroupNo int, FirstName varchar(255), Value int)

INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 60)
INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 50)
INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 40)
INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 30)
INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 20)
INSERT INTO #MATCHEDADDITION VALUES(1, 'john', 10)

INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 80)
INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 50)
INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 40)
INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 30)
INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 20)
INSERT INTO #MATCHEDADDITION VALUES(1, 'adam', 10)

INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 60)
INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 50)
INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 40)
INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 30)
INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 20)
INSERT INTO #MATCHEDADDITION VALUES(2, 'jill', 10)

INSERT INTO #MATCHEDADDITION VALUES(2, 'toni', 90)
INSERT INTO #MATCHEDADDITION VALUES(2, 'toni', 50)
INSERT INTO #MATCHEDADDITION VALUES(2, 'toni', 40)
INSERT INTO #MATCHEDADDITION VALUES(2, 'toni', 30)

INSERT INTO #MATCHEDADDITION VALUES(2, 'tami', 80)
INSERT INTO #MATCHEDADDITION VALUES(2, 'tami', 50)
INSERT INTO #MATCHEDADDITION VALUES(2, 'tami', 40)
INSERT INTO #MATCHEDADDITION VALUES(2, 'tami', 30)
INSERT INTO #MATCHEDADDITION VALUES(2, 'tami', 20)

DROP TABLE #MATCHEDADDITION

which has the following values:

1   john    60
1   john    50
1   john    40
1   john    30
1   john    20
1   john    10
1   adam    80
1   adam    50
1   adam    40
1   adam    30
1   adam    20
1   adam    10
2   jill    60
2   jill    50
2   jill    40
2   jill    30
2   jill    20
2   jill    10
2   toni    90
2   toni    50
2   toni    40
2   toni    30
2   tami    80
2   tami    50
2   tami    40
2   tami    30
2   tami    20

What I am trying to do is to apply an operator on values that are obtained in a certain way: The values in each group should first be aligned column-wise based on the minimum number of records available for a group member. An example should explain this. In the above table, I want to first arrange the values like this:

Members of Group 1
                -
60 80        |
50 50        |
40 40        |    Arrange these like this and apply a custom 
30 30        |    operator on the row elements i.e. say addition 
20 20        |    on 60,80 and 50,50 and 40,40 etc.
10 10        |
                -
Members of Group 2

            -
60 90 80     |
50 50 50     |
40 40 40     |   The size of this is only 4 because that is the min size of a 
30 30 30     |   member 'toni' in this group
            -

I don't consider myself an expert in SQL but wanted to know if this is even possible to do using a query or I should go for the conventional approach of cursors or perhaps operate offline using a scripting language. Any suggestions?

Upvotes: 2

Views: 90

Answers (1)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239664

This gets you six results to work with in Group 1 and 4 results to work with in Group 2. Within each group, the rn column describes "matching" rows. I'm still not sure how to apply the function you're trying to describe to get to a final output yet (nor even how to derive a column number, cn, to correspond with the row numbers rn assigned):

;with Numbered as (
    select *,
      ROW_NUMBER() OVER (
           PARTITION BY GroupNo,FirstName
           ORDER BY Value desc) as rn
    from #MATCHEDADDITION
), RNs as (
    select GroupNo,rn,COUNT(*) as Cnt
    from Numbered
    group by GroupNo,rn
), MaxGroups as (
    select GroupNo,MAX(rn) as maxRN
    from RNs
    where Cnt = (select MAX(Cnt) from RNs n where n.GroupNo = RNs.GroupNo)
    group by GroupNo
)
select
    n.*
from
    Numbered n
        inner join
    MaxGroups mg
        on
            n.GroupNo = mg.GroupNo and
            n.rn <= mg.maxRN

(I also have a nagging feeling I can make this prettier, use fewer CTEs, etc)

Results (thus far):

GroupNo     FirstName Value       rn
----------- --------- ----------- --------------------
1           adam      80          1
1           adam      50          2
1           adam      40          3
1           adam      30          4
1           adam      20          5
1           adam      10          6
1           john      60          1
1           john      50          2
1           john      40          3
1           john      30          4
1           john      20          5
1           john      10          6
2           jill      60          1
2           jill      50          2
2           jill      40          3
2           jill      30          4
2           tami      80          1
2           tami      50          2
2           tami      40          3
2           tami      30          4
2           toni      90          1
2           toni      50          2
2           toni      40          3
2           toni      30          4

Upvotes: 2

Related Questions