我有一个体育项目。
Country League StartDate EndDate
------------------------------------------------------------
USA UPA 10.10.2015 13.06.2018
当我使用下面的代码时,我得到的结果如上所述。
SELECT Country
,League
,MIN(MatchDateTimeUtc) AS StartDate
,MAX(MatchDateTimeUtc) AS EndDate
FROM Games
WHERE Country = 'USA'
GROUP BY Country
,League
我需要按日期范围标记季节。 但是日期范围不是恒定的。 我的意思是每个联赛的开始或结束日期不确定。 任何联赛的开始或结束日期可能会改变。 只有国家和联赛领域是不变的。 例如,实际上以上结果有3个赛季。 我的预期结果如下。
Country League StartDate EndDate
------------------------------------------------------------
USA UPA 10.10.2015 09.04.2016
USA UPA 22.10.2016 11.05.2017
USA UPA 30.09.2017 13.06.2018
有什么聪明的逻辑吗?
答案 0 :(得分:1)
显然,您需要更多有关如何区分不同季节的游戏的信息。
最简单的示例是进行限制性假设,例如“所有季节的游戏都在同一年,并且每年仅包含1个季节的游戏”。在这种情况下,您可以按年份将分组添加为wel,例如:year(startDate)
:
SELECT Country,
League,
MIN(MatchDateTimeUtc) AS StartDate,
MAX(MatchDateTimeUtc) AS EndDate
FROM Games
WHERE Country = 'USA'
GROUP BY Country, League, year(startDate)
如果无法解决关于季节的这种简单约定,那么您需要为League_seasons引入另一个表,并加入League_season表进行分组。
由于“季节”是由OP注释定义的,是根据游戏之间的间隔时间定义的,因此您可以使用以下查询:
;with removedDuplicates as (
select distinct * from games
),
gamesWithSeasonNumber AS (
select g.*,
SUM(
case when not exists (
select 1 from removedDuplicates previousG
where previousG.Country = g.Country and previousG.League = g.League
and previousG.MatchDateTimeUtc < g.MatchDateTimeUtc
and (DATEDIFF(d, previousG.MatchDateTimeUtc, g.MatchDateTimeUtc) < 60))
then 1 else 0
end)
OVER(Partition By Country, LEague ORDER BY MatchDateTimeUtc) as SeasonNumber
from removedDuplicates g
)
select Country, League, min(MatchDateTimeUtc) as startDate, max(MatchDateTimeUtc) as EndDate
from gamesWithSeasonNumber
group by Country, League, SeasonNumber
该解决方案的关键部分是:
Common Table Expressions,以逐步保持查询的可读性。
答案 1 :(得分:0)
根据您的样本数据,可以通过减去8个月并使用年份来计算季节:
SELECT Country, League,
MIN(MatchDateTimeUtc) AS StartDate,
MAX(MatchDateTimeUtc) AS EndDate
FROM Games
WHERE Country = 'USA'
GROUP BY Country, League,
YEAR(DATEADD(month, -8, startDate));
这应该适用于从9月-12月到8月之前结束的任何季节。您的所有数据都支持该定义。如果您有更详细的数据,我真的建议您再问一个问题,以更好地定义“季节”和更好的原始数据示例。