首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于查找最长连胜的SQL查询

用于查找最长连胜的SQL查询
EN

Stack Overflow用户
提问于 2019-02-15 16:40:49
回答 6查看 886关注 0票数 2

我有如下数据-

代码语言:javascript
运行
复制
Year,winning_country
2001,IND
2002,IND
2003,IND
2004,AUS
2005,AUS
2006,SA
2007,SA
2008,SA
2009,IND
2010,IND
2011,IND
2012,IND
2013,AUS
2014,AUS
2015,SA
2016,NZ
2017,SL
2018,IND

这里的问题是找出每个国家的最长连胜,所需的产出如下所示-

代码语言:javascript
运行
复制
Country,no_of_wins
IND,4
AUS,2
SA,3
SL,1
NZ,1

有人能帮帮忙吗。

EN

回答 6

Stack Overflow用户

发布于 2019-02-15 20:44:56

这是一个差距和孤岛问题,但最简单的方法是从年份中减去一个序列。因此,要获得所有序列:

代码语言:javascript
运行
复制
select country, count(*) as streak,
       min(year) as from_year, max(year) as to_year
from (select year, country,
             row_number() over (partition by country order by year) as seqnum
      from t
     ) t
group by country, (year - seqnum);

要获得每个国家/地区的最长时间,请再次聚合或使用窗口函数:

代码语言:javascript
运行
复制
select country, streak
from (select country, count(*) as streak,
             min(year) as from_year, max(year) as to_year,
             row_number() over (partition by country order by count(*) desc) as seqnum_2
      from (select year, country,
                   row_number() over (partition by country order by year) as seqnum
            from t
           ) t
      group by country, (year - seqnum)
     ) cy
where seqnum_2 = 1;

我更喜欢使用row_number()来获得最长的条纹,因为它还允许您获得它发生的年份。

票数 3
EN

Stack Overflow用户

发布于 2019-02-15 17:31:19

如果Redshift支持解析函数,则查询如下。

代码语言:javascript
运行
复制
with t1 as 
(
select 2001 as year,'IND' as cntry from dual union
select 2002,'IND' from dual union
select 2003,'IND' from dual union
select 2004,'AUS' from dual union
select 2005,'AUS' from dual union
select 2006,'SA' from dual union
select 2007,'SA' from dual union
select 2008,'SA' from dual union
select 2009,'IND' from dual union
select 2010,'IND' from dual union
select 2011,'IND' from dual union
select 2012,'IND' from dual union
select 2013,'AUS' from dual union
select 2014,'AUS' from dual union
select 2015,'SA' from dual union
select 2016,'NZ' from dual union
select 2017,'SL' from dual union
select 2018,'IND' from dual) ,
t2 as (select year, cntry, year - row_number() over (partition by cntry order by year) as grpBy from t1 order by cntry),
t3 as (select cntry, count(grpBy) as consWins from t2 group by cntry, grpBy),
res as (select cntry, consWins, row_number() over (partition by cntry order by consWins desc) as rnk from t3)
select cntry, consWins from res where rnk=1;

希望这能有所帮助。

票数 0
EN

Stack Overflow用户

发布于 2019-02-15 17:36:44

以下是利用Redshift Python UDF的使用的解决方案

可能有更简单的方法来实现同样的目的,但这是如何创建简单的UDF的一个很好的例子。

代码语言:javascript
运行
复制
create table temp_c (competition_year int ,winning_country varchar(4));
insert into temp_c (competition_year, winning_country)
values
(2001,'IND'),
(2002,'IND'),
(2003,'IND'),
(2004,'AUS'),
(2005,'AUS'),
(2006,'SA'),
(2007,'SA'),
(2008,'SA'),
(2009,'IND'),
(2010,'IND'),
(2011,'IND'),
(2012,'IND'),
(2013,'AUS'),
(2014,'AUS'),
(2015,'SA'),
(2016,'NZ'),
(2017,'SL'),
(2018,'IND')
;

create or replace function find_longest_streak(InputStr varChar)
  returns integer
stable
as $$
    MaxStreak=0
    ThisStreak=0
    ThisYearStr=''
    LastYear=0
    for ThisYearStr in InputStr.split(','):
        if int(ThisYearStr) == LastYear + 1:
            ThisStreak+=1
        else:
            if ThisStreak > MaxStreak:
                MaxStreak=ThisStreak
            ThisStreak=1
        LastYear=int(ThisYearStr)
    return max(MaxStreak,1)
$$ language plpythonu;

select winning_country,
       find_longest_streak(listagg(competition_year,',') within group (order by competition_year))
from temp_c
group by winning_country
order by 2 desc
;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54705406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档