Reputation: 116820
I have a vague idea of how to do this using CURSOR
s 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
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