Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Скрипты для статистической утилиты  [new]
DelphiTankDriver
Member

Откуда:
Сообщений: 5
Приветствую всех форумчан!

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

Таблица stat упрощенно имеет такую структуру
stat_id ключ
tank_id внешний ключ, указывает на описание модели танка
battle_time время в бою, сек
battle количество проведенных боев
total_xp накопленный опыт
damage_infl нанесенный урон
и т.д.

Для одной модели танка в этой таблице содержится несколько записей у которых в частности значение поля battle увеличивается от записи к записи. Вот таким запросом я могу выбрать все записи относящиеся к заданному танку:
select t.name, s.* from tank t
inner join stat s
on s.tank_id=t.tank_id
where t.name='E-75'
ORDER BY battle DESC

и получаю нечто вроде этого

name	stat_id	time	xp	battle		damage
E-75	188	72277	161211	186		379453
E-75	187	71847	159876	185		376659
E-75	184	71508	159563	184		375539
E-75	183	71348	159229	183		374355
E-75	182	71089	157606	182		372477
E-75	181	69124	155679	181		368459
E-75	180	68642	154545	180		366411
E-75	178	68426	153008	179		362413
E-75	176	67514	151820	177		359960
E-75	173	53632	120499	138		285770
E-75	171	47173	108797	124		258967
E-75	166	45279	104437	118		246009
E-75	164	40857	98483	111		229677
E-75	156	33305	76799	88		177662

Теперь что собственно говоря мне надо. Я хочу на основании ук.таблицы вычислить разницу между строками и, таким образом, получить значения параметров (нанесенный урон и т.п.) для каждого боя (а если разница в значении battle > 1 то просто усреднить).

Я сделал отдельную таблицу diff, которая почти полностью повторяет stat, но в ней есть два поля stat1 и stat2 которые хранят ид записей над которыми была взята разница и написал скрипт который для заданных строк из stat формирует строку в diff:

insert into diff(stat_1,stat_2,tank_id,total_xp,battle,damage_infl)
select  180,178,s1.tank_id,
        s1.total_xp-s2.total_xp as total_xp,
        s1.battle-s2.battle as battle,
        s1.damage_infl-s2.damage_infl as damage_infl
        from stat s1, stat s2 where s1.stat_id=183 and s2.stat_id=182

Как вы видите, номера записей 180 и 178 прописаны в этом скрипте жестко. Собственно вопрос.

Как автоматизировать перебор всех пар записей из stat для заполнения таблицы diff. Для описанного примера надо выполнить скрипт над парами записей:
164 156
166 164
171 166
...
188 187

Т.к. я SQL не знаю (кроме простых вариантов SELECT и INSERT), то не могу понять как лучше это сделать. В самой программе я конечно могу получить таблицу и передрать все в цикле, но моет есть более красивое решение на SQL?

зы. В таблице stat я также предусмотрел поле diff_calc которое служит признаком того была ли выполнена операция вычисления разницы для данной записи.
22 сен 11, 13:26    [11318755]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
DelphiTankDriver
Member

Откуда:
Сообщений: 5
Немного напутал номера записей в примере. Так правильно

insert into diff(stat_1,stat_2,tank_id,total_xp,battle,damage_infl)
select 180,178,s1.tank_id,
s1.total_xp-s2.total_xp as total_xp,
s1.battle-s2.battle as battle,
s1.damage_infl-s2.damage_infl as damage_infl
from stat s1, stat s2 where s1.stat_id=180 and s2.stat_id=178
22 сен 11, 13:34    [11318837]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
DelphiTankDriver
Member

Откуда:
Сообщений: 5
Спасибо за помощь. Можно закрывать тему.

select  zz.stat1, zz.stat2, s1.tank_id,

        (s1.total_xp-s2.total_xp)/b as total_xp,
        s1.battle-s2.battle as b,
        s1.damage_infl-s2.damage_infl as damage_infl

        from
         
         stat s1,
         
         stat s2,
         
         (select s1.stat_id as stat1, max(s2.stat_id) as stat2
          from stat s1, stat s2
          where s1.battle>s2.battle and s1.tank_id=131 and s2.tank_id=131
          group by s1.stat_id) zz
         
         where s1.stat_id=zz.stat1 and s2.stat_id=zz.stat2
22 сен 11, 15:27    [11319886]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
iljy
Member

Откуда:
Сообщений: 8711
DelphiTankDriver,

че-то вы сложное делаете. Вам вот это нужно?
declare @t table (name varchar(10), stat_id	int, time int,xp int, battle int, damage int)
insert @t values
('E-75','188','72277','161211','186','379453'),
('E-75','187','71847','159876','185','376659'),
('E-75','184','71508','159563','184','375539'),
('E-75','183','71348','159229','183','374355'),
('E-75','182','71089','157606','182','372477'),
('E-75','181','69124','155679','181','368459'),
('E-75','180','68642','154545','180','366411'),
('E-75','178','68426','153008','179','362413'),
('E-75','176','67514','151820','177','359960'),
('E-75','173','53632','120499','138','285770'),
('E-75','171','47173','108797','124','258967'),
('E-75','166','45279','104437','118','246009'),
('E-75','164','40857','98483','111','229677'),
('E-75','156','33305','76799','88','177662')

;with cte as(
	select *, ROW_NUMBER() over(partition by name order by battle) RN
	from @t
)
select *
from cte t1 left join cte t2 on t1.name = t2.name and t1.RN+1 = t2.RN
22 сен 11, 15:34    [11319942]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
DelphiTankDriver
Member

Откуда:
Сообщений: 5
Не могу проверить скрипт, т.к. выдает ошибку, но если он получает что то типо этого как результат, то да это то что нужно

164	156	131	942	23	2261
166	164	131	850	7	2333
171	166	131	726	6	2159
173	171	131	835	14	1914
176	173	131	803	39	1902
178	176	131	594	2	1226
180	178	131	1537	1	3998
181	180	131	1134	1	2048
182	181	131	1927	1	4018
183	182	131	1623	1	1878
184	183	131	334	1	1184
187	184	131	313	1	1120
188	187	131	1335	1	2794
22 сен 11, 15:51    [11320100]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
DelphiTankDriver
Member

Откуда:
Сообщений: 5
Проблема то в том, что разница между stat_1 и stat_2 не всегла равна 1. Игрок же может поочередно катать разные танки, тогда для заданного танка записи для последнего и предпоследнего боя могут быть например 180 и 193.
22 сен 11, 15:58    [11320164]     Ответить | Цитировать Сообщить модератору
 Re: Скрипты для статистической утилиты  [new]
iljy
Member

Откуда:
Сообщений: 8711
DelphiTankDriver,

какую ошибку и какая версия сервера? Скрипт показывает, как можно соединить строку с предыдущей, а дальше считайте по этим данным что хотите.
22 сен 11, 16:20    [11320414]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить