SQL保龄球分数计算

时间:2013-11-30 21:19:13

标签: sql sql-server

我仍然是一个SQL菜鸟,我一直在努力解决这个问题很长一段时间,最后我的智慧结束了,因此我必须寻求帮助。 我试图计算一个保龄球游戏的得分,但不明白如何在同一个表中的列上进行数学运算,并且当它是一个开放的框架,打击或备用,以及第10帧时,将逻辑放入处理。保存游戏数据的表是:

TYearLeagueGamePlayerFrameThrows
     intYearID
    ,intLeagueID
    ,intTeamID
    ,intGameID
    ,intGameSetIndex
    ,intPlayerID
    ,intFrameID
    ,intTurnID
    ,intThrowPinCount

因此,对于一个保龄球游戏,插页看起来像:

             ( 1, 1, 1, 1, 1, 1, 1, 1, 9 )  
        ,( 1, 1, 1, 1, 1, 1, 1, 2, 1 ) 
        ,( 1, 1, 1, 1, 1, 1, 2, 1, 8 )
        ,( 1, 1, 1, 1, 1, 1, 2, 2, 0 )
        ,( 1, 1, 1, 1, 1, 1, 3, 1, 10 )
        ,( 1, 1, 1, 1, 1, 1, 4, 1, 10 )
        ,( 1, 1, 1, 1, 1, 1, 5, 1, 7 )
        ,( 1, 1, 1, 1, 1, 1, 5, 2, 2 )
        ,( 1, 1, 1, 1, 1, 1, 6, 1, 9 )
        ,( 1, 1, 1, 1, 1, 1, 6, 2, 0 )
        ,( 1, 1, 1, 1, 1, 1, 7, 1, 6 )
        ,( 1, 1, 1, 1, 1, 1, 7, 2, 3 )
        ,( 1, 1, 1, 1, 1, 1, 8, 1, 1 )
        ,( 1, 1, 1, 1, 1, 1, 8, 2, 9 )
        ,( 1, 1, 1, 1, 1, 1, 9, 1, 7 )
        ,( 1, 1, 1, 1, 1, 1, 9, 2, 2 ) 
        ,( 1, 1, 1, 1, 1, 1, 10, 1, 9 )
        ,( 1, 1, 1, 1, 1, 1, 10, 2, 1 )
        ,( 1, 1, 1, 1, 1, 1, 10, 3, 8 )

非常感谢任何帮助!!

到目前为止我唯一能够提出的是这个,但总数是错误的:

  DECLARE    @TurnID    AS INTEGER
        ,@Count     AS INTEGER
        ,@Frame     AS INTEGER
        ,@Score     AS INTEGER
        ,@Value     AS INTEGER
        ,@Throw1    AS INTEGER
        ,@Throw2    AS INTEGER
        ,@Throw3    AS INTEGER
        ,@Throw4    AS INTEGER
        ,@Total     AS INTEGER

SELECT 
    TOP 21 
    intTurnID 
    ,intPlayerID 

FROM 
     TYearLeagueTeamPlayerGameFrameThrows 

WHERE
    intPlayerID = @intPlayerID 
ORDER BY

      intTurnID 
     ,intFrameID 

SET @Count      = @@ROWCOUNT 
SET @TurnID     = 1
SET @Frame      = 0
SET @Score      = 0
SET @Total      = 0

WHILE @Frame < 10 AND @TurnID < @Count 
    BEGIN

    SET @Frame  = @Frame + 1


SELECT 
    @Throw1 = intThrowPinCount 
FROM 
    TYearLeagueTeamPlayerGameFrameThrows 
WHERE
    intFrameID  = 1
AND 
    intThrowPinCount = @TurnID 

SELECT
    @Throw2 = intThrowPinCount 
FROM
    TYearLeagueTeamPlayerGameFrameThrows 
WHERE
    intFrameID  = 1
AND 
    intThrowPinCount = @TurnID + 1

SELECT 
    @Throw3 = intThrowPinCount
FROM
    TYearLeagueTeamPlayerGameFrameThrows 
WHERE
    intFrameID = 2
AND 
    intThrowPinCount = @TurnID + 2


SET @Value = 
    CASE
    WHEN @Throw1            = 10 THEN @Throw1 + @Throw2 + @Throw3 --STRIKE
    WHEN @Throw1 + @Throw2  = 10 THEN @Throw1 + @Throw2 + @Throw3 --SPARE
    ELSE @Throw1 + @Throw2 

END

SET @TurnID = @TurnID + 
    CASE 
    WHEN @Throw1            = 10 THEN 3 --STRIKE
    WHEN @Throw1 + @Throw2  = 10 THEN 2 --SPARE
    ELSE 1

END

SET @Score = @Score + @Value 
    IF @Throw1 + @Throw2 <= 10 or @Throw3 IS NOT NULL
        PRINT 'FRAME: ' + str(@Frame, 2 ) + '  Score: ' + str(@Score, 3 )  
END

框架和游戏应该总是:

Frame 1 = 18
Frame 2 = 26
Frame 3 = 53
Frame 4 = 72
Frame 5 = 81
Frame 6 = 90
Frame 7 = 99
Frame 8 = 116
Frame 9 = 125
Frame 10 = 143 - Final Score

2 个答案:

答案 0 :(得分:1)

以下内容可能看起来很复杂,但它在SQL-Server(或大多数其他SQL)中运行准确。首先,最内层的查询。在这里,我创建了一个关于每年,联赛,团队,游戏,集合和玩家分组的交叉表。

我明确地做了一个案例/什么时候为每个可能的帧和镜头创建一个单独的行,这样它将类似于保龄球游戏,其中列名称为“F”rame +“S”hot,以便F1S1 = Frame1,Shot1,F1S2 = Frame1,Shot2,在第10帧中,F10S1,F10S2 F10S3。所以现在我们每个人都会累积到PER GAME,PER Set等单行,我们现在可以逐帧计算得分。

所以,对于每一帧,我正在做一个case / when并明确复制所有10帧,因为每帧可以依赖UP到以下2帧,我想你会直接遵循逻辑。

我正在测试双电流和下一帧是罢工,因为这是与任何一组帧进行比较的最多。如此。

If    Frame1 Shot1 is 10 (strike) 
  AND Frame2 Shot1 is 10 (strike), then 20 + whatever was Frame3 Shot1

If    Frame1 Shot1 is 10 (strike)
  AND Frame2 Shot1 is LESS than 10, then 10 + BOTH shots in Frame2

If neither condition in Frame 1 was a strike, test for a spare
if   Frame1 Shot1 + Frame1 Shot2 is 10 (spare), then 10 + first shot in Frame2

if neither a strike or a spare, just add Frame1 Shot1 + Frame1 Shot2.

Take that result and apply the same, but shift for the represenative frames.
If Frame2 Shot1 is 10 and Frame3 Shot1 is 10, then 20 + Frame4 Shot1
etc...

select
      Game.intYearID,
      Game.intLeagueID,
      Game.intTeamID,
      Game.intGameID,
      Game.intGameSetIndex,
      Game.intPlayerID,
      case when Game.F1S1 = 10 and Game.F2S1 = 10 then 20 + Game.F3S1
           when Game.F1S1 = 10 and Game.F2S1 < 10 then 10 + Game.F2S1 + Game.F2S2
           when Game.F1S1 + Game.F1S2 = 10 then 10 + Game.F2S1
           else Game.F1S1 + Game.F1S2 end
    +  case when Game.F2S1 = 10 and Game.F3S1 = 10 then 20 + Game.F4S1
           when Game.F2S1 = 10 and Game.F3S1 < 10 then 10 + Game.F3S1 + Game.F3S2
           when Game.F2S1 + Game.F2S2 = 10 then 10 + Game.F3S1
           else Game.F2S1 + Game.F2S2 end
    +  case when Game.F3S1 = 10 and Game.F4S1 = 10 then 20 + Game.F5S1
           when Game.F3S1 = 10 and Game.F4S1 < 10 then 10 + Game.F4S1 + Game.F4S2
           when Game.F3S1 + Game.F3S2 = 10 then 10 + Game.F4S1
           else Game.F3S1 + Game.F3S2 end
    +  case when Game.F4S1 = 10 and Game.F5S1 = 10 then 20 + Game.F6S1
           when Game.F4S1 = 10 and Game.F5S1 < 10 then 10 + Game.F5S1 + Game.F5S2
           when Game.F4S1 + Game.F4S2 = 10 then 10 + Game.F5S1
           else Game.F4S1 + Game.F4S2 end
    +  case when Game.F5S1 = 10 and Game.F6S1 = 10 then 20 + Game.F7S1
           when Game.F5S1 = 10 and Game.F6S1 < 10 then 10 + Game.F6S1 + Game.F6S2
           when Game.F5S1 + Game.F5S2 = 10 then 10 + Game.F6S1
           else Game.F5S1 + Game.F5S2 end
    +  case when Game.F6S1 = 10 and Game.F7S1 = 10 then 20 + Game.F8S1
           when Game.F6S1 = 10 and Game.F7S1 < 10 then 10 + Game.F7S1 + Game.F7S2
           when Game.F6S1 + Game.F6S2 = 10 then 10 + Game.F7S1
           else Game.F6S1 + Game.F6S2 end
    +  case when Game.F7S1 = 10 and Game.F8S1 = 10 then 20 + Game.F9S1
           when Game.F7S1 = 10 and Game.F8S1 < 10 then 10 + Game.F8S1 + Game.F8S2
           when Game.F7S1 + Game.F7S2 = 10 then 10 + Game.F8S1
           else Game.F7S1 + Game.F7S2 end
    +  case when Game.F8S1 = 10 and Game.F9S1 = 10 then 20 + Game.F10S1
           when Game.F8S1 = 10 and Game.F9S1 < 10 then 10 + Game.F9S1 + Game.F9S2
           when Game.F8S1 + Game.F8S2 = 10 then 10 + Game.F9S1
           else Game.F8S1 + Game.F8S2 end
    +  case when Game.F9S1 = 10 and Game.F10S1 = 10 then 20 + Game.F10S2
           when Game.F9S1 = 10 and Game.F10S1 < 10 then 10 + Game.F10S1 + Game.F10S2
           when Game.F9S1 + Game.F9S2 = 10 then 10 + Game.F10S1
           else Game.F9S1 + Game.F9S2 end
    +  case when Game.F10S1 = 10 and Game.F10S2 = 10 then 20 + Game.F10S3
           when Game.F10S1 = 10 and Game.F10S2 < 10 then 10 + Game.F10S2 + Game.F10S3
           when Game.F10S1 + Game.F10S2 = 10 then 10 + Game.F10S3
           else Game.F10S1 + Game.F10S2 end
      as GameScore
   from 
      ( select
              TY.intYearID,
              TY.intLeagueID,
              TY.intTeamID,
              TY.intGameID,
              TY.intGameSetIndex,
              TY.intPlayerID,
              sum( case when TY.intFrameID = 1 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F1S1,
              sum( case when TY.intFrameID = 1 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F1S2,
              sum( case when TY.intFrameID = 2 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F2S1,
              sum( case when TY.intFrameID = 2 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F2S2,
              sum( case when TY.intFrameID = 3 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F3S1,
              sum( case when TY.intFrameID = 3 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F3S2,
              sum( case when TY.intFrameID = 4 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F4S1,
              sum( case when TY.intFrameID = 4 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F4S2,
              sum( case when TY.intFrameID = 5 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F5S1,
              sum( case when TY.intFrameID = 5 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F5S2,
              sum( case when TY.intFrameID = 6 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F6S1,
              sum( case when TY.intFrameID = 6 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F6S2,
              sum( case when TY.intFrameID = 7 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F7S1,
              sum( case when TY.intFrameID = 7 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F7S2,
              sum( case when TY.intFrameID = 8 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F8S1,
              sum( case when TY.intFrameID = 8 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F8S2,
              sum( case when TY.intFrameID = 9 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F9S1,
              sum( case when TY.intFrameID = 9 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F9S2,
              sum( case when TY.intFrameID = 10 and TY.intTurnID = 1 then TY.intThrowPinCount else 0 end ) F10S1,
              sum( case when TY.intFrameID = 10 and TY.intTurnID = 2 then TY.intThrowPinCount else 0 end ) F10S2,
              sum( case when TY.intFrameID = 10 and TY.intTurnID = 3 then TY.intThrowPinCount else 0 end ) F10S3
           from
              TYearLeagueGamePlayerFrameThrows TY
           group by
              TY.intYearID,
              TY.intLeagueID,
              TY.intTeamID,
              TY.intGameID,
              TY.intGameSetIndex,
              TY.intPlayerID ) Game

所以,现在,如果你想从数据得到前21个分数,那就做一个

order by
   GameScore DESC

答案 1 :(得分:0)

我不知道保龄球,但这可能是一个开始(原谅我重新命名的专栏):


select FrameId, sum(ThrowPinCount)
, scorecard = (case when isStrike = 1 then 'X'  
               when sum(ThrowPinCount) = 10 then '/' 
               else cast(sum(ThrowPinCount) as nvarchar(5)) end)
from (
    select FrameId, TurnID, ThrowPinCount
    , isStrike = (case when ThrowPinCount = 10 then 1 else 0 end)
    from #YearLeagueGamePlayerFrameThrows
) results
group by FrameID, isstrike
order by frameid