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

Откуда:
Сообщений: 15
есть таблица турниров - tours
есть таблица игр - games
еще есть таблица игроков в турнирах - usersINtours

Вопрос - Подскажите пожалуйста, как получить турнирную таблицу,
вроде такой(на этой схеме знак'-' обозначает пробел)

--игроки----1-2-3---очки----место
-----------------------------------
1-Иванов----х-1-1----2-------1
2-Сидоров---0-х-1----1-------2
3-Петров----0-0-х----0-------3

программа на ASP.NET C# и SQL Server
Надо срочно и за любую цену
31 июл 09, 20:52    [7486601]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Виталик Чекменев
за любую цену
€1 000 000 000, - и турнирная таблица Ваша!
31 июл 09, 21:06    [7486631]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Supra93
Member

Откуда:
Сообщений: 8174
iap
Виталик Чекменев
за любую цену
€1 000 000 000, - и турнирная таблица Ваша!

€900 000 000
31 июл 09, 21:40    [7486683]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
Если число участников турнира точно известно, можно попробовать через pivot:
declare @names table(id int identity, fio varchar(30))
declare @results table(wnr int,lsr int) -- id победителя, id проигравшего

insert into @names(fio) select 'Ivanov'union all select 'Sidorov' union all select 'Petrov'
insert into @results(wnr,lsr) 
select 1,2 union all select 1,3 union all select 2,3

select *,p=rank()over(order by score desc)
from(
select id,fio
,r1=case when id=1 then 'x' else cast(isnull([1],0)as varchar) end
,r2=case when id=2 then 'x' else cast(isnull([2],0)as varchar) end
,r3=case when id=3 then 'x' else cast(isnull([3],0)as varchar) end
,score=isnull(sign([1]),0)+isnull(sign([2]),0)+isnull(sign([3]),0)
from(
  select id,fio,r1.wnr,r1.lsr
    from @names n
    left join @results r1 on n.id=r1.wnr
  )ps
  pivot(max(wnr) for lsr in ([1],[2],[3]))pv
)t
1 авг 09, 11:05    [7487294]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Виталик Чекменев
Member

Откуда:
Сообщений: 15
Большое спасибо всем ответившим и особенно Оззи Осборну.
Надо срочно и за любую цену - не обижайтесь, но это "для красного словца".
Максимальное вознаграждение - пиво. много пива. Кого не устраивает такое вознаграждение сообщите свои реальные условия.

Дополнительные требоавния к заданию:
Участники должны быть отсортированны по коэфициенту Бергера -
В круговых турнирах, где за победу, ничью и поражение присуждается определённое постоянное число очков (например, в шахматах за победу даётся 1 очко, за ничью — 0,5 очка, за поражение — 0 очков), часто случается так, что два или несколько участников набирают одинаковое количество очков. Чтобы определить, кто из этих участников занял более высокое место, подсчитывают коэффициенты Бергера участников.

Коэффициент Бергера определённого участника складывается из суммы всех очков противников, у которых данный участник выиграл, плюс половина суммы очков противников, с которыми данный участник сыграл вничью. Идея, на которой базируется коэффициент: из двух участников, равных по числу очков, сильнее тот, кто выиграл у более сильных противников, то есть у тех, кто набрал больше очков. Поэтому участнику, имеющему больший коэффициент Бергера, присуждается более высокое итоговое место в турнире.


Итоговая таблица гипотетического кругового турнира:
Участники 1 2 3 4 5 6 7 Очки КБ Место
Иванов х 1/2 1/2 1 1 1 1 5 11,75 I
Петров 1/2 х 1/2 1/2 1 1 1 4,5 10 II
Сидоров 1/2 1/2 х 1/2 1/2 1 1 4 9 III
Кузнецов 0 1/2 1/2 х 1 1 1 4 7,75 IV
Смирнов 0 0 1/2 0 х 1 1 2,5 3 V
Васильев 0 0 0 0 0 х 1 1 0 VI
Николаев 0 0 0 0 0 0 х 0 0 VII

Обозначения: 1 — победа, 1/2 — ничья, 0 — поражение, КБ — коэффициент Бергера

Участники Сидоров и Кузнецов набрали одинаковое количество очков, по 4 очка. Кто из них займет третье место, решается по коэффициенту Бергера.

Коэффициент Бергера участника Сидорова складывается так: 2,5 (половина очков Иванова) + 2,25 (половина очков Петрова) + 2 (половина очков Кузнецова) + 1,25 (половина очков Смирнова) + 1 (все очки Васильева) + 0 (все очки Николаева) = 9.

Коэффициент Бергера участника Кузнецова так: 0 (за поражение от Иванова) + 2,25 (половина очков Петрова) + 2 (половина очков Сидорова) + 2,5 (все очки Смирнова) + 1 (все очки Васильева) + 0 (все очки Николаева) = 7,75.

Таким образов участник Сидоров имеет более высокий коэффициент Бергера чем участник Кузнецов (9 против 7,75), поэтому третье место присуждается Сидорову. Коэффициент Бергера более высок у того, кто выигрывает или добивается ничьей с более сильными игроками (игроками набирающих большее количество очков). В приведённом примере выигрыш у участника, имеющего ноль очков, не даёт вклада в коэффициент Бергера.

Таблицы SQL Server:

1.Tours с полями
TourID int,
TourName nvarchar(100),
Status nvarchar(4)

2. TourUser с полями
TourID int,
UserName nvarchar(20)

3. Games с полями
GameID int
TourID int,
PlayerWhite nvarchar(20),
PlayerBlack nvarchar(20),
State nvarchar(3) -это результат '1-0' - победа PlayerWhite, '0-1' - победа PlayerBlack, '1/2' - ничья, '_' - партия незакончена
3 авг 09, 13:28    [7490643]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
автор
Таблицы SQL Server: 1.Tours с полями ...
Правильно ли я понял, что это таблица есть справочник турниров, а не отдельных туров ?
и еще: число участников в каждом турнире будет туров - оно фиксированное или "плавающее", т.е. сегодня 2, завтра 200 етц ?
3 авг 09, 22:13    [7492733]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
2 топегстартер:
Вообще, нельзя ли привести скрипт с данными под ту таблицу, которая нарисована ?
Непонятно, к примеру, каким образом 7 участников (нечётное число!) могут в одном туре встретиться друг с другом.
PS. Немного не по теме, но всё же: зачем в таблице Games в полях PlayerWhite nvarchar(20) и PlayerBlack nvarchar(20) повторяются ФИО участников ? вы же сами для них ID'шники создали в таблице Users.
3 авг 09, 23:10    [7492873]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Виталик Чекменев
Member

Откуда:
Сообщений: 15
Ozzy-Osbourne
автор
Таблицы SQL Server: 1.Tours с полями ...
Правильно ли я понял, что это таблица есть справочник турниров, а не отдельных туров ?
и еще: число участников в каждом турнире будет туров - оно фиксированное или "плавающее", т.е. сегодня 2, завтра 200 етц ?


Это справочник турниров(а не туров), и я думаю, что нам эта таблица совсем не нужна для получения Турнирной таблицы.

Да, в разных турнирах разное количество участников. от 4 до 19.
4 авг 09, 15:01    [7496144]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Виталик Чекменев
Member

Откуда:
Сообщений: 15
Ozzy-Osbourne
2 топегстартер:
Вообще, нельзя ли привести скрипт с данными под ту таблицу, которая нарисована ?
Непонятно, к примеру, каким образом 7 участников (нечётное число!) могут в одном туре встретиться друг с другом.
PS. Немного не по теме, но всё же: зачем в таблице Games в полях PlayerWhite nvarchar(20) и PlayerBlack nvarchar(20) повторяются ФИО участников ? вы же сами для них ID'шники создали в таблице Users.


К сожаления скрипта нет... пока ничего нет. Тоесть есть, но только в голове.

7 участников встречаются друг с другом по круговой системе в 6 турах(играх).

Таблицы Users нет. Тоесть она есть, но гдето далеко... на другом серваке.

А вместо ID'ишников как раз имена участников - это уникальное поле.
4 авг 09, 15:06    [7496173]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
автор
К сожаления скрипта нет... пока ничего нет. Тоесть есть, но только в голове.
ну, тогда приведите его тут, плз. Чтобы он отражал именно ту таблицу с 7 участниками, которую вы нарисовали. К примеру, что конкретно надо затолкать в таблицу Games ?
4 авг 09, 15:36    [7496396]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Виталик Чекменев
Member

Откуда:
Сообщений: 15
Ozzy-Osbourne
автор
К сожаления скрипта нет... пока ничего нет. Тоесть есть, но только в голове.
ну, тогда приведите его тут, плз. Чтобы он отражал именно ту таблицу с 7 участниками, которую вы нарисовали. К примеру, что конкретно надо затолкать в таблицу Games ?



GameID TourID PlayerWhite PlayerBlack State
1 1 Петров Иванов 1/2
2 1 Иванов Сидоров 1/2
3 1 Кузнецов Иванов 0-1
4 1 Иванов Смирнов 1-0
5 1 Васильев Иванов 0-1
6 1 Иванов Николаев 1-0
7 1 Сидоров Петров 1/2
8 1 Петров Кузнецов 1/2
9 1 Смирнов Петров 0-1
10 1 Петров Васильев 1-0
11 1 Николаев Петров 0-1
12 1 Кузнецов Сидоров 1/2
13 1 Сидоров Смирнов 1/2
14 1 Васильев Сидоров 0-1
15 1 Сидоров Николаев 1-0
16 1 Смирнов Кузнецов 0-1
17 1 Кузнецов Васильев 1-0
18 1 Николаев Кузнецов 0-1
19 1 Васильев Смирнов 0-1
21 1 Смирнов Николаев 1-0
21 1 Николаев Васильев 0-1


спрашивайте любые вопросы
4 авг 09, 17:56    [7497465]     Ответить | Цитировать Сообщить модератору
 Re: Как получить турнирную таблицу  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
автор
спрашивайте любые вопросы

Забирайте свой чемодан. Как работать с такой схемой - не знаю. Примите соболезнования :-)
--declare @tours table(t_id int, nm varchar(100), st varchar(4))
declare @users table(t_id int,nm varchar(20))
declare @games table(g_id int,t_id int,pWhite varchar(20),pBlack varchar(20), st varchar(3))

--insert into @tours(t_id,nm,st) select 1,'Kopenhagen','cool'
insert into @users(t_id,nm) select 1,'Иванов' union all select 1,'Петров' union all select 1,'Сидоров' union all select 1,'Кузнецов' union all select 1,'Смирнов' union all select 1,'Васильев' union all select 1,'Николаев'
insert into @games(g_id,t_id,pWhite,pBlack,st)
select 1,       1,       'Петров',   'Иванов'   ,  '1/2' union all
select 2,       1,       'Иванов',   'Сидоров'  ,  '1/2' union all
select 3,       1,       'Кузнецов', 'Иванов'   ,  '0-1' union all
select 4,       1,       'Иванов',   'Смирнов'  ,  '1-0' union all
select 5,       1,       'Васильев', 'Иванов'   ,  '0-1' union all
select 6,       1,       'Иванов',   'Николаев' ,  '1-0' union all
select 7,       1,       'Сидоров',  'Петров'   ,  '1/2' union all
select 8,       1,       'Петров',   'Кузнецов' ,  '1/2' union all
select 9,       1,       'Смирнов',  'Петров'   ,  '0-1' union all
select 10,      1,       'Петров',   'Васильев' ,  '1-0' union all
select 11,      1,       'Николаев', 'Петров'   ,  '0-1' union all
select 12,      1,       'Кузнецов', 'Сидоров'  ,  '1/2' union all
select 13,      1,       'Сидоров',  'Смирнов'  ,  '1/2' union all
select 14,      1,       'Васильев', 'Сидоров'  ,  '0-1' union all
select 15,      1,       'Сидоров',  'Николаев' ,  '1-0' union all
select 16,      1,       'Смирнов',  'Кузнецов' ,  '0-1' union all
select 17,      1,       'Кузнецов', 'Васильев' ,  '1-0' union all
select 18,      1,       'Николаев', 'Кузнецов' ,  '0-1' union all
select 19,      1,       'Васильев', 'Смирнов'  ,  '0-1' union all
select 21,      1,       'Смирнов',  'Николаев' ,  '1-0' union all
select 22,      1,       'Николаев', 'Васильев' ,  '0-1'

;with
pList as
(
  select u.nm,opp=case when nm=pWhite then pBlack else pWhite end
        ,stx=case st when '1-0' then '1.0.' when '0-1' then '0.1.' else '.5.5' end
        ,pWhite,pBlack
    from @users u left join @games g  on u.t_id=g.t_id and u.nm in (g.pBlack,g.pWhite)
)
,pSums as
(
  select nm,scsum=sum(cast(case when nm=pWhite then left(stx,2) else right(stx,2) end as float))
  from pList t
  group by nm
)

,pRes as
(
  select nm,opp,sc,BergerCoeff,playerScore,playerRank=dense_rank()over(order by playerScore desc,BergerCoeff)
  from(
  select nm,opp,sc,playerScore=sum(sc)over(partition by nm),BergerCoeff=sum(sc*oppsc)over(partition by nm)
  from(
  select t.nm,opp,sc=cast(case when t.nm=t.pWhite then left(stx,2) else right(stx,2) end as float),oppsc=s.scsum
  from pList t
  join pSums s on t.opp=s.nm 
  )t
  )t
)
--select * from pres

select nm
,[1]=isnull(cast(max([1])as char(3)), ' x ')
,[2]=isnull(cast(max([2])as char(3)), ' x ')
,[3]=isnull(cast(max([3])as char(3)), ' x ')
,[4]=isnull(cast(max([4])as char(3)), ' x ')
,[5]=isnull(cast(max([5])as char(3)), ' x ')
,[6]=isnull(cast(max([6])as char(3)), ' x ')
,[7]=isnull(cast(max([7])as char(3)), ' x ')
,playerScore,BergerCoeff,playerRank
from(
  select *,r=case when oppRank>playerRank then 1 else 0 end + t.rs
  from(
  select r1.nm,opp,sc,playerScore,r1.BergerCoeff,r1.playerRank,oppRank=r2.playerRank,oppBergerCoeff=r2.BergerCoeff
        ,rs=row_number()over(partition by r1.nm order by r1.BergerCoeff-r2.BergerCoeff)
    from pRes r1 join (select distinct nm,playerRank,BergerCoeff from pRes)r2 on r1.opp=r2.nm
  )t
)p
pivot( max(sc) for r in ([1],[2],[3],[4],[5],[6],[7]))pv
group by playerRank,playerScore,nm,BergerCoeff

PS. Место участника вместо римских цифр выведено арабскими. Также ничьи вместо "1/2" показаны как "0.5"
6 авг 09, 21:39    [7508206]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить