Sql 如何获得三连胜

Sql 如何获得三连胜,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,这是表格: ([TeamA],[TeamB],[Win],[date]) ('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'

这是表格:

([TeamA],[TeamB],[Win],[date])

('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)
要求的答案应该是连续赢3场的球队和计数。在这里,例如RR和妈妈将连续三次获胜。KKR有3场胜利,但是如果我们看到日期列,它不是连续的3场,因此KKR不应该出现在答案中,输出应该是

RR 1
MUM 1

我的方法可能是以更干净的方式进行:

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;
输出:

╔══════╦══════════════════════╗
║ team ║ Number_of_hat_tricks ║
╠══════╬══════════════════════╣
║ MUM  ║                    1 ║
║ RR   ║                    1 ║
╚══════╩══════════════════════╝
工作原理:

cte-集合所有团队 cte2-为每支球队寻找对手,并检查球队是否获胜 cte3-添加需求编号 cte4-计算每个岛的长度 最终-获得岛>=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

缺口和岛屿。计算每个岛的长度。最后的计数是岛的长度除以3整除,丢弃小数部分

我又添加了几行A队和B队,以说明A队4胜,B队7胜,A队4胜,这导致A队和B队的最终计数分别为2和2

样本数据

质疑

通常情况下,你会在一个单独的表中列出一个团队列表,在这里,我将它构建在一个CTE_团队中。CTE_计数在每一个连续的连胜中有3连胜的数量。由于一支球队可能会有多场连胜,请参见a队,我们将进一步总结这一点。团队可以按任意顺序列在TeamA和TeamB列中,因此在交叉应用中的WHERE中有一个OR来捕获这两个变体

因此,对于每个团队,只选择与该团队相关的行。这是通过交叉应用完成的

然后,通过使用不同的分区对行进行两次编号来创建经典的间隙和孤岛。行号的差异给出了组孤岛和间隙

筛选CTE_Teams.Team=CA。Win只留下获胜团队的孤岛

按CTE_团队分组。团队给出岛屿的大小,即连续获胜的次数

查询在SQLServer2008中工作

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;
结果


不使用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
输出

试试这个简单的查询

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
资料

)

选择abc,从ipl中选择先赢后输的案例teama 选择b.win,counthatrick/3作为编号 从ipl b加入 选择a.win,算作hatrick 从ipl a在a.win=b.win上加入ipl b 其中a.day全部 选择abc.day 从abc加入ipl a于a.win=abc.LOSS 其中abc.lose=b.win和abc.day=3组由b.win


嘿,伙计们,我用过这个版本。让我知道这方面是否有任何问题

什么是您的dbms、mysql或sql server?以及什么的计数?他们有多少次连续三次获胜?请把你的问题说清楚,我不明白。RR在第4、5、7天获胜。妈妈在第2、7、8天赢了。他们如何获得资格?我看到KKR只有3场胜利。我认为你的例子是错误的。请再说一遍,因为他们已经连续赢了3场比赛,我的意思是说,无论这几天的差距有多大,他们已经连续赢了3场,而KKR还没有赢t@SouravA开始阅读KKR’,‘妈妈’,‘妈妈’,2,它失去了妈妈,所以它有赢-失败-赢-赢正在通过你的个人资料。在5个月的时间内获得22500分!你太棒了!谢谢你,小伙子!这是一个超级快速的反应,效果非常好。我写了一个简短的版本,因为我不知道你用了多少概念。我将分享我的版本
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  |
+------+-------------+
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)