Redshift:在列表中查找 MAX,忽略非增量数字
Redshift: Find MAX in list disregarding non-incremental numbers
我在一家体育电影分析公司工作。我们有具有唯一团队 ID 的团队,我想找到从今天开始他们将电影上传到我们网站的连续周数。每个上传在单独的 table 中也有自己的行,我可以加入 teamid 并且有一个唯一的上传日期。到目前为止,我整理了一个简单的查询,该查询提取每个唯一的 DATEDIFF(week) 值和 teamid 上的组。
Select teamid, MAX(weekdiff)
(Select teamid, DATEDIFF(week, dateuploaded, GETDATE()) as weekdiff
from leroy_events
group by teamid, weekdiff)
我得到的是一个 teamID 列表和独特的每周日期差异。然后我想在不破坏 1 增量的情况下找到每个 teamID 的最大值。例如,如果我的数据集是:
Team datediff
11453 0
11453 1
11453 2
11453 5
11453 7
11453 13
我希望团队的最大值:11453 为 2。
任何想法都会很棒。
我已经简化了你的例子,假设我已经有一个 table 和 weekdiff
列。这就是你用 DATEDIFF
计算它的方法。
首先,我使用 LAG()
window 函数将 weekdiff 的先前值(在有序集中)分配给当前行。
然后,使用 WHERE
条件,我正在检索 max(weekdiff)
值,该值具有连续 weekdiff
的先前值 current_value - 1
。
数据:
create table leroy_events ( teamid int, weekdiff int);
insert into leroy_events values (11453,0),(11453,1),(11453,2),(11453,5),(11453,7),(11453,13);
代码:
WITH initial_data AS (
Select
teamid,
weekdiff,
lag(weekdiff,1) over (partition by teamid order by weekdiff) as lag_weekdiff
from
leroy_events
)
SELECT
teamid,
max(weekdiff) AS max_weekdiff_consecutive
FROM
initial_data
WHERE weekdiff = lag_weekdiff + 1 -- this insures retrieving max() without breaking your consecutive increment
GROUP BY 1
SQLFiddle 与您的示例数据一起查看此代码的工作原理。
结果:
teamid max_weekdiff_consecutive
11453 2
您可以使用 SQL window 函数来探测 table 的行之间的关系。在这种情况下,lag()
函数可用于查看相对于给定顺序和分组的前一行。这样您就可以确定给定的行是否属于一组连续的行。
您仍然需要整体聚合或过滤以将每个感兴趣的组(即每个团队)的行数减少到 1。在这种情况下聚合很方便。总的来说,它可能看起来像这样:
select
team,
case min(datediff)
when 0 then max(datediff)
else -1
end as max_weeks
from (
select
team,
datediff,
case
when (lag(datediff) over (partition by team order by datediff) != datediff - 1)
then 0
else 1
end as is_consec
from diffs
) cd
where is_consec = 1
group by team
内联视图只是向数据添加一个 is_consec
列,标记每一行是否是一组连续行的一部分。外部查询对该列进行过滤(您不能直接对 window 函数进行过滤),并从每个团队的剩余行中选择最大值 datediff
。
这里有一些细微之处:
内联视图中的 case
表达式是按原样编写的,以利用这样一个事实,即为每个分区的第一行计算的 lag()
将是 NULL
,它不会评估不等于(或等于)任何值。因此,每个分区中的第一行始终标记为连续。
外部 select
子句中的 case
testing min(datediff)
选取没有 datediff = 0
记录的团队,并分配 -1
到第 max_weeks
列。
如果他们组中的第一个没有datediff = 0
,也可以将行标记为不连续,但这样你就会从结果中完全失去这些团队。
我在一家体育电影分析公司工作。我们有具有唯一团队 ID 的团队,我想找到从今天开始他们将电影上传到我们网站的连续周数。每个上传在单独的 table 中也有自己的行,我可以加入 teamid 并且有一个唯一的上传日期。到目前为止,我整理了一个简单的查询,该查询提取每个唯一的 DATEDIFF(week) 值和 teamid 上的组。
Select teamid, MAX(weekdiff)
(Select teamid, DATEDIFF(week, dateuploaded, GETDATE()) as weekdiff
from leroy_events
group by teamid, weekdiff)
我得到的是一个 teamID 列表和独特的每周日期差异。然后我想在不破坏 1 增量的情况下找到每个 teamID 的最大值。例如,如果我的数据集是:
Team datediff
11453 0
11453 1
11453 2
11453 5
11453 7
11453 13
我希望团队的最大值:11453 为 2。
任何想法都会很棒。
我已经简化了你的例子,假设我已经有一个 table 和 weekdiff
列。这就是你用 DATEDIFF
计算它的方法。
首先,我使用 LAG()
window 函数将 weekdiff 的先前值(在有序集中)分配给当前行。
然后,使用 WHERE
条件,我正在检索 max(weekdiff)
值,该值具有连续 weekdiff
的先前值 current_value - 1
。
数据:
create table leroy_events ( teamid int, weekdiff int);
insert into leroy_events values (11453,0),(11453,1),(11453,2),(11453,5),(11453,7),(11453,13);
代码:
WITH initial_data AS (
Select
teamid,
weekdiff,
lag(weekdiff,1) over (partition by teamid order by weekdiff) as lag_weekdiff
from
leroy_events
)
SELECT
teamid,
max(weekdiff) AS max_weekdiff_consecutive
FROM
initial_data
WHERE weekdiff = lag_weekdiff + 1 -- this insures retrieving max() without breaking your consecutive increment
GROUP BY 1
SQLFiddle 与您的示例数据一起查看此代码的工作原理。
结果:
teamid max_weekdiff_consecutive
11453 2
您可以使用 SQL window 函数来探测 table 的行之间的关系。在这种情况下,lag()
函数可用于查看相对于给定顺序和分组的前一行。这样您就可以确定给定的行是否属于一组连续的行。
您仍然需要整体聚合或过滤以将每个感兴趣的组(即每个团队)的行数减少到 1。在这种情况下聚合很方便。总的来说,它可能看起来像这样:
select
team,
case min(datediff)
when 0 then max(datediff)
else -1
end as max_weeks
from (
select
team,
datediff,
case
when (lag(datediff) over (partition by team order by datediff) != datediff - 1)
then 0
else 1
end as is_consec
from diffs
) cd
where is_consec = 1
group by team
内联视图只是向数据添加一个 is_consec
列,标记每一行是否是一组连续行的一部分。外部查询对该列进行过滤(您不能直接对 window 函数进行过滤),并从每个团队的剩余行中选择最大值 datediff
。
这里有一些细微之处:
内联视图中的
case
表达式是按原样编写的,以利用这样一个事实,即为每个分区的第一行计算的lag()
将是NULL
,它不会评估不等于(或等于)任何值。因此,每个分区中的第一行始终标记为连续。外部
select
子句中的case
testingmin(datediff)
选取没有datediff = 0
记录的团队,并分配-1
到第max_weeks
列。如果他们组中的第一个没有
datediff = 0
,也可以将行标记为不连续,但这样你就会从结果中完全失去这些团队。