MS SQL 2000 - Как эффективно пройти через набор предыдущих записей и обработать их в группах. Большой стол - PullRequest
0 голосов
/ 21 февраля 2011

Я бы хотел проконсультироваться с одной вещью. У меня есть таблица в БД. Он имеет 2 столбца и выглядит так:

Название ... Bilance

Джейн ... + 3
Джейн ...- 5
Джейн ... 0
Джейн ...- 8
Джейн ...- 2
Павел ...- 1
Пол ... 2
Paul .... 9
Павел ... 1
...

Мне нужно пройтись по этой таблице, и если я найду запись с другим «именем» (чем было в предыдущем ряду), я обработаю все строки с предыдущим «именем». (Если я наступаю на первую строку Пола, я обрабатываю все строки Джейн)

Обработка идет так:

Теперь я работаю только с записями Джейн и прохожу их один за другим. На каждой записи я останавливаюсь и сравниваю ее со всеми предыдущими строками Джейн по одной.

Задача состоит в том, чтобы суммировать столбец "bilance" (в поле зрения реального человека), если они имеют разные знаки

Резюме:

Я циклически перебираю эту таблицу в 3-х уровнях (вложенные циклы)
1-й уровень = поиск изменений в столбце «имя»
2-й уровень = если изменение было найдено, возьмите все строки с предыдущим «именем» и пройдитесь по ним
3-й уровень = на каждой строке останавливаться и проходить все предыдущие строки с текущим «именем»

Это можно решить только с помощью CURSOR и FETCHING, или есть более плавное решение?

Моя настоящая таблица насчитывает 30 000 строк и 1500 человек, и если я делаю логику в PHP, это займет много минут и тайм-аутов. Поэтому я хотел бы переписать его в MS SQL 2000 (другие БД не разрешены). Являются ли курсоры быстрым решением или лучше использовать что-то еще?

Спасибо за ваше мнение.

UPDATE:

Есть много вопросов по поводу моего "обобщения". Проблема немного сложнее, чем я объяснил. Я упростил это только для описания моего алгоритма.

Каждая строка в моей таблице содержит гораздо больше столбцов. Самый важный месяц. Вот почему есть больше строк для каждого человека. Каждый на разный месяц.
«Bilances» - это «сверхурочные» и «просроченные часы» работников. И мне нужно подвести итоги + и -, чтобы нейтрализовать их, используя значения предыдущих месяцев. Я хочу иметь как можно больше нулей. Вся таблица должна оставаться такой, какая есть, просто необходимо сменить нули.

Пример:

Строка (Джейн -5) будет суммироваться со строкой (Джейн +3). Вместо 3 я получу 0, а вместо -5 я получу -2. Потому что я использовал это -5, чтобы уменьшить +3.
Следующая строка (Джейн 0) не пострадает
Следующая строка (Jane -8) не может быть использована, потому что все предыдущие операции отрицательны
и т.д.

Ответы [ 3 ]

0 голосов
/ 21 февраля 2011

На первый взгляд звучит так, как будто это должно делать то, что вы хотите:

select Name, sum(bilance)
from table
group by Name
order by Name

Если нет, вам, возможно, придется уточнить, как сортируются имена и что вы подразумеваете под «суммированием»..

0 голосов
/ 21 февраля 2011

Я не уверен, что вы подразумеваете под этой строкой ... "Задача состоит в том, чтобы подытожить столбец" bilance "(в поле зрения реального человека), если они имеют разные знаки".

Но может быть возможно использовать группу по запросу, чтобы получить много того, что вам нужно.

select name, case when bilance < 0 then 'negative' when bilance >= 0 then 'positive', count(*)
from table
group by name, bilance

Это может быть не идеальный синтаксис для оператора case, но этоочень близко.

0 голосов
/ 21 февраля 2011

Вы можете суммировать все значения на имя, используя один оператор SQL:

select
    name,
    sum(bilance) as bilance_sum
from
    my_table
group by
    name
order by
    name
...