如何在不使用CURSORS或脚本语言的情况下处理此问题?

时间:2011-07-28 06:15:32

标签: sql sql-server sql-server-2008

我对如何使用CURSOR进行此操作有一个模糊的想法,但我仍然试图花一些时间思考如何在不使用它们的情况下执行此操作。我有一张这样的桌子:

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

具有以下值:

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

我要做的是对以某种方式获得的值应用运算符:每个组中的值应首先根据组成员可用的最小记录数进行逐列对齐。一个例子应该解释这个。在上表中,我想首先安排这样的值:

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
            -

我不认为自己是SQL方面的专家,但想知道这是否可以使用查询,或者我应该采用传统的游标方法,或者使用脚本语言离线操作。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

这将使您在第1组中使用6个结果,在第2组中使用4个结果。在每个组中,rn列描述“匹配”行。我仍然不确定如何应用您尝试描述的函数来获得最终输出(甚至不知道如何派生列号cn,以与行号{{1}对应已分配):

rn

(我也有一种唠叨的感觉,我可以让这个更漂亮,使用更少的CTE等)

结果(迄今为止):

;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