Redshift:在列表中查找 MAX 忽略非增量数字
Posted
技术标签:
【中文标题】Redshift:在列表中查找 MAX 忽略非增量数字【英文标题】:Redshift: Find MAX in list disregarding non-incremental numbers 【发布时间】:2015-11-23 22:30:18 【问题描述】:我在一家体育电影分析公司工作。我们有具有唯一团队 ID 的团队,我想找出他们从今天开始向后将电影上传到我们网站的连续周数。每个上传在单独的表格中也有自己的行,我可以加入 teamid 并有一个唯一的上传日期。到目前为止,我整理了一个简单的查询,该查询提取了每个唯一的 DATEDIFF(week) 值和 teamid 上的组。
Select teamid, MAX(weekdiff)
(Select teamid, DATEDIFF(week, dateuploaded, GETDATE()) as weekdiff
from leroy_events
group by teamid, weekdiff)
我得到的是一个团队 ID 列表和唯一的每周日期差异。然后我想在不破坏 1 的增量的情况下找到每个 teamID 的最大值。例如,如果我的数据集是:
Team datediff
11453 0
11453 1
11453 2
11453 5
11453 7
11453 13
我希望团队的最大值:11453 为 2。
任何想法都会很棒。
【问题讨论】:
【参考方案1】:假设我已经有一个带有weekdiff
列的表,我已经简化了您的示例。这就是你用DATEDIFF
来计算它所做的事情。
首先,我使用LAG()
窗口函数将weekdiff 的前一个值(在有序集中)分配给当前行。
然后,使用WHERE
条件,我正在检索max(weekdiff)
值,该值具有先前的值,即current_value - 1
连续weekdiff
s。
数据:
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
【讨论】:
非常感谢您的帮助。这是否也会影响在频谱后期开始的数字系列?例如,具有 45、46、47 的 weekdiff 数据集的团队......此查询会返回 47,还是根本不返回?如果是返回47,有没有办法完全不返回? 我在上面评论中的问题可能已经被约翰在下面的回答中回答了。他能够进行 CASE 比较,看看 MIN 是否等于 0。结合您在这里的回答,看起来我有一个很棒的最终产品! 是的,这是可能的,但我看到 John 已经在这方面为您提供了帮助。请记住为帮助您解决问题的答案投票。【参考方案2】:您可以使用 SQL 窗口函数来探测表中各行之间的关系。在这种情况下,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
列,标记每一行是否是一组连续行的一部分。外部查询对该列进行过滤(您不能直接在窗口函数上进行过滤),并从每个团队的剩余行中选择最大的datediff
。
这里有一些微妙之处:
内联视图中的case
表达式按原样编写,以利用为每个分区的第一行计算的lag()
将是NULL
,它不会计算不等(也不等于)任何值。因此,每个分区中的第一行总是被标记为连续的。
外部select
子句中的case
测试min(datediff)
会选择没有datediff = 0
记录的团队,并将-1
分配给max_weeks
列。
如果他们组中的第一个没有datediff = 0
,也可以将行标记为非连续行,但这样你就会从结果中完全失去这些团队。
【讨论】:
以上是关于Redshift:在列表中查找 MAX 忽略非增量数字的主要内容,如果未能解决你的问题,请参考以下文章
如果未提供列列表,Redshift COPY 命令将忽略表默认值
RegEx(在 JavaScript 中查找/替换) - 匹配非字母数字字符但忽略 - 和 +