Как мне подойти к этому без использования курсоров или скриптового языка? - PullRequest
2 голосов
/ 28 июля 2011

У меня есть смутное представление о том, как сделать это, используя CURSOR s, но я все еще пытаюсь потратить некоторое время на размышления о том, как сделать это, не используя их. У меня есть такая таблица:

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 Ответ

2 голосов
/ 28 июля 2011

Это дает вам шесть результатов для работы в группе 1 и результаты 4 для работы в группе 2. В каждой группе столбец rn описывает «совпадающие» строки.Я до сих пор не знаю, как применить функцию, которую вы пытаетесь описать, чтобы получить окончательный вывод (и даже не узнать, как получить номер столбца, cn, чтобы соответствовать назначенным номерам строк rn):

;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

(у меня также есть ноющее чувство, что я могу сделать это красивее, использовать меньше CTE и т. Д.)

Результаты (пока):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...