如何连续赢得三场胜利

时间:2015-12-16 10:18:52

标签: sql sql-server sql-server-2008

这是表格:

@Pathvariable

所需的答案应该是连续3次获胜的球队和计数。这里例如RR和MUM连续三次获胜。 KKR有3胜,但如果我们看到日期列不是连续3,那么KKR不应该在答案中,输出应该是

   @RequestMapping(value="/{projectName}/job", method=RequestMethod.GET)
   @ResponseBody
    public String test(@Pathvariable("projectName") String projectName) throws Exception{
      ...
   }

5 个答案:

答案 0 :(得分:3)

我的方法(可能以更干净的方式完成):

WITH cte AS
(
  SELECT TeamA AS team FROM #tab
  UNION 
  SELECT TeamB FROM #tab
), cte2 AS 
(
  SELECT c.team
      ,[opponent] = CASE WHEN c.team = t.teamA THEN t.teamB ELSE t.teamA END
      ,t.[win]
      ,t.[day]
      ,[is_winner] = CASE WHEN c.team = t.[win] THEN 1 ELSE 0 END
  FROM cte c
  JOIN #tab t
    ON c.team = t.teamA
    OR c.team = t.teamB
), cte3 AS
(
  SELECT team, [day], [is_winner],
    r =  ROW_NUMBER() OVER (PARTITION BY team ORDER BY [day])
  FROM cte2
), cte4 AS
(
  SELECT team, Length = MAX(r) - MIN(r) + 1 
  FROM (SELECT team, r
          ,rn=r-ROW_NUMBER() OVER (PARTITION BY team ORDER BY r)
        FROM cte3
        WHERE is_winner = 1) a
  GROUP BY team, rn
)
SELECT team, SUM(Length/3) AS [Number_of_hat_tricks] 
FROM cte4
WHERE Length >= 3
GROUP BY team;

LiveDemo

输出:

╔══════╦══════════════════════╗
║ team ║ Number_of_hat_tricks ║
╠══════╬══════════════════════╣
║ MUM  ║                    1 ║
║ RR   ║                    1 ║
╚══════╩══════════════════════╝

工作原理:

  • cte - 获取所有球队
  • cte2 - 为每支球队找到对手并检查球队是否获胜
  • cte3 - 添加连续数字
  • cte4 - 计算每个岛屿的长度
  • final - 获取岛屿> = 3并将它们相加(整数除法用于计算行中的6个胜利,行数为2和9,为3,...)

最后一个想法:

最后一列中的值必须与同一团队唯一:

('RR','CSK','RR',7)
('CSK','MUM','MUM',7)

CSK vs RR - 7
CSK vs MUM - 7

使用当前数据无法以稳定的方式对其进行排序。所以应该是时间日期部分:

CSK vs RR  2015-12-07 10:00
CSK vs MUM 2015-12-07 21:00       -- now we know that it is the second match

答案 1 :(得分:1)

隙和 - 岛屿。计算每个岛的长度。最终计数是岛的长度除以3(整数除法,丢弃小数部分)。

我添加了更多行(团队AB)来说明4胜A,然后7胜B,然后4胜{{1}再次,这导致AA的最终计数为2和2。

示例数据

B

<强>查询

通常你会在一个单独的表中有一个团队列表,在这里我用DECLARE @T TABLE (TeamA varchar(50), TeamB varchar(50), Win varchar(50), dt int); INSERT INTO @T (TeamA, TeamB, Win, dt) VALUES ('KKR','HYD','KKR',1), ('KKR','MUM','MUM',2), ('RCB','HYD','HYD',3), ('DEL','PUB','PUB',4), ('RR','PUB','RR',4), ('RR','DEL','RR',5), ('RCB','CSK','CSK',6), ('RR','CSK','RR',7), ('CSK','MUM','MUM',7), ('MUM','DEL','MUM',8), ('HYD','PUNE','PUNE',9), ('PUB','DEL','DEL',9), ('KKR','DEL','KKR',10), ('KKR','RCB','KKR',10), ('A','B','A',11), ('A','B','A',12), ('A','B','A',13), ('A','B','A',14), ('A','B','B',15), ('A','B','B',16), ('A','B','B',17), ('A','B','B',18), ('A','B','B',19), ('A','B','B',20), ('A','B','B',21), ('A','B','A',22), ('A','B','A',23), ('A','B','A',24), ('A','B','A',25); 构建它。 CTE_Teams每连续连胜的数量为CTE_Counts。由于团队可能会出现多次连胜(见团队3-wins-in-a-row),因此可以进一步总结。团队可以按ATeamA列中的任意顺序列出,因此在TeamB内的WHERE中有一个CROSS APPLY来捕获这两种变体。< / p>

因此,对于每个团队,只选择与该团队相关的行。这是由OR完成的。

然后,经典CROSS APPLY通过使用不同的分区对行进行两次编号。行数的差异给出了组(岛和间隙)。

过滤器gaps-and-islands只留下获胜团队的岛屿。

WHERE CTE_Teams.Team = CA.Win分组给出了岛屿的大小,即连续获胜的数量。

查询在SQL Server 2008中有效。

CTE_Teams.Team

<强>结果

WITH
CTE_Teams
AS
(
    SELECT T.TeamA AS Team
    FROM @T AS T

    UNION -- sic! not ALL

    SELECT T.TeamB AS Team
    FROM @T AS T
)
,CTE_Counts
AS
(
    SELECT
        CTE_Teams.Team
        --,CA.Win
        --,rn1 - rn2 AS GroupNumber
        --,COUNT(*) AS GroupSize
        ,COUNT(*) / 3 AS FinalCount
    FROM
        CTE_Teams
        CROSS APPLY
        (
            SELECT
                T.Win
                ,T.dt
                ,ROW_NUMBER() OVER (PARTITION BY CTE_Teams.Team 
                    ORDER BY T.dt, T.TeamA, T.TeamB) AS rn1
                ,ROW_NUMBER() OVER (PARTITION BY CTE_Teams.Team, T.Win 
                    ORDER BY T.dt, T.TeamA, T.TeamB) AS rn2
            FROM @T AS T
            WHERE
                T.TeamA = CTE_Teams.Team
                OR T.TeamB = CTE_Teams.Team
        ) AS CA
    WHERE
        CTE_Teams.Team = CA.Win
    GROUP BY
        CTE_Teams.Team
        ,CA.Win
        ,rn1 - rn2
    HAVING COUNT(*) / 3 > 0
)
SELECT
    CTE_Counts.Team
    ,SUM(CTE_Counts.FinalCount) AS FinalCount
FROM CTE_Counts
GROUP BY CTE_Counts.Team
ORDER BY CTE_Counts.Team;

SQL Fiddle

答案 2 :(得分:1)

在不使用CTE的情况下解决此问题的另一种方法是:

create table #a
(
teama varchar(10), teamb varchar(10), win varchar(10), dat int)

insert into #a
values
('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5),
('RCB','CSK','CSK',6),
('RR','CSK','RR',7),
('CSK','MUM','MUM',7),
('MUM','DEL','MUM',8),
('HYD','PUNE','PUNE',9),
('PUB','DEL','DEL',9),
('KKR','DEL','KKR',10),
('KKR','RCB','KKR',10);

select 
team, 
win,
row_number() over (partition by team order by dat) matchnum
into #res
  from 
    (
    select teamA team, case when teamA = win then 1 else 0 end as win, dat
    from #a 
    union all
    select teamB team, case when teamB = win then 1 else 0 end , dat
    from #a 
    )A 
order by team,dat


select 
    match1.team, count(*)/3 + 1 cntHatricks
from #res match1 join #res match2 
    on match1.team = match2.team and match2.matchnum = match1.matchnum+1
join #res match3 on match1.team = match3.team and match3.matchnum = match1.matchnum+2
where 
    match1.win = 1 and match2.win = 1 and match3.win = 1            
    group by match1.team

<强>输出

+------+-------------+
| Team | cntHatricks |
+------+-------------+
| MUM  |          1  |
| RR   |          1  |
+------+-------------+

答案 3 :(得分:1)

尝试这个简单的查询

select  tm,sum(case when win=tm  then 1 else 0 end)/3 hattrick from @a a
inner join (select teama tm from @a union select teamb from @a) t on a.win=t.tm 
group by tm
having count(distinct dat)>2

数据

declare @a table 
(teama varchar(10), teamb varchar(10), win varchar(10), dat int)
insert into @a
values
('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5),
('RCB','CSK','CSK',6),
('RR','CSK','RR',7),
('CSK','MUM','MUM',7),
('MUM','DEL','MUM',8),
('HYD','PUNE','PUNE',9),
('PUB','DEL','DEL',9),
('KKR','DEL','KKR',10),
('KKR','RCB','KKR',10)

答案 4 :(得分:0)

用abc作为(选择,案例茶时获胜然后茶叶其他茶叶结束从ipl输掉)    (选择b.win,计数(hatrick)/ 3作为数字    来自ipl b加入        (选择a.win,计数()为hatrick         来自ipl a加入ipl b on a.win = b.win
        其中a.day&lt; b.day和a.day&gt;所有             (选择abc.day
            从abc加入ipl a on a.win = abc.lose
            在哪里abc.lose = b.win和abc.day&lt; b.day)
            a.win小组)d             在b.win = d.win
            其中hatrick&gt; = 3组by b.win)

嘿伙计们,我使用过这个版本。如果这个

中有任何故障,请告诉我