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 连续weekdiffs。

数据:

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 命令将忽略表默认值

Redshift 中的增量负载

在 Redshift 中查找常用连接查询

RegEx(在 JavaScript 中查找/替换) - 匹配非字母数字字符但忽略 - 和 +

将数据从 sql server 增量上传到 Amazon Redshift [关闭]

Redshift 表 - 查找表上查询的最后日期