仅在某些条件下使用 Redshift 中的 SQL 对具有相同名称的行进行分组

Posted

技术标签:

【中文标题】仅在某些条件下使用 Redshift 中的 SQL 对具有相同名称的行进行分组【英文标题】:Group rows with same name only under certain conditions with SQL in redshift 【发布时间】:2018-11-20 11:05:43 【问题描述】:

现在我有一个包含网页数据的表格,如下所示:

 Visitor_ID  Visit_ID  visit_time  pagepath         page seq    timestart        timeend
   0001       0111      2018-11-19  /homepage          1         ...              ...
   0001       0111      2018-11-19  /someotherpage     2         ...              ...
   0001       0111      2018-11-19  /product           3     2018-11-19 23:05  2018-11-19 23:15
   0001       0111      2018-11-19  /product           4     2018-11-19 23:15  2018-11-19 23:16
   0001       0111      2018-11-19  /product           5     2018-11-19 23:16  2018-11-19 23:17
   0001       0111      2018-11-19  /someotherpage     6         ...              ...   
   0001       0111      2018-11-19  /someotherpage     7         ...              ...  
   0001       0111      2018-11-19  /product           8     2018-11-19 23:25  2018-11-19 23:26

原始数据有错误,部分页面重复,我想要的是将重复的部分分组,就像页面序列3,4,5一样,总结时间浏览就像:

 Visitor_ID  Visit_ID  visit_time  pagepath   page seq     timestart        timeend
   0001       0111      2018-11-19  /product      3     2018-11-19 23:05  2018-11-19 23:17
   ...
   ...
   0001       0111      2018-11-19  /product      8     2018-11-19 23:25  2018-11-19 23:26

我使用了 group by 并取了最小值。但是问题是,在这种情况下,第 8 页是一次有效的访问,它也会被分组,这不是我们想要的结果

我也尝试过使用滞后和分区解决方案,但问题是

我只能得到

之后的行

而且记录之间的复制次数不同,无法通过固定代码解决

总的来说,我想将具有相同页面路径的记录分组并对其进行总结,但同时保持相同的页面路径不是重复记录。有谁知道如何在 redshift 中这样做?

非常感谢您提前提供的帮助

【问题讨论】:

... (ellipses) 通常表示“采用与上述相同的模式”。这使您的示例看起来像第 6 行和第 7 行也适用于 /product。我建议您输入一个不同的值 (如 /smeg 以明确说明这些不是 /product) 行。 您使用什么逻辑来确定记录 8 是有效的页面访问,而记录 3-7 是重复的(它是非重叠记录,即 timeend 和 timestart 是连续的吗? 还请提供您尝试过的代码,例如LAG(),并显示您得到的结果、错误的原因以及您希望它做哪些不同的事情。阅读本文可能会帮助您澄清您的问题:***.com/help/mcve @GeorgeJoseph - 如果您再次阅读它并阅读我的评论,我很确定 OP 意味着说只有 3 , 4, 5 是重复的,而 6, 7 是完全不同的东西。这使得使用 ... 成为一个非常令人困惑的坏主意。 @MatBailie 是的,你是对的。第 6,7 列有点不同,它只是为了说明第 8 行,它们具有相同的值但应该被视为有效。顺便说一句,非常感谢! 【参考方案1】:

假设在您的帖子中... 的意思是“这里有些不同”(与“这里更多相同”的实际含义相反)那么您似乎想要一个“差距和岛屿”的解决方案。

我会发布答案,你看看它是否有效。但是解释是冗长的,您需要搜索 SO 以查找其他 gaps-and-islands 答案以找到各种解释。

SELECT
  Visitor_ID,
  Visit_ID,
  MIN(visit_time)  AS visit_time,
  pagepath,
  MIN(page_seq)    AS page_seq,
  MIN(timestart)   AS timestart,
  MAX(timeend)     AS timeend
FROM
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY Visitor_ID, Visit_ID, pagepath
                           ORDER BY page_seq
                      )
                         AS pagepath_seq
  FROM
    yourTable
)
  AS sequenced
GROUP BY
  Visitor_ID,
  Visit_ID,
  pagepath,
  pagepath_seq - page_seq

(假设page_seq 从 1 开始,从不存在任何间隙,并为每个 Visitor_ID/Visit_ID “重新启动”。)

例如:https://dbfiddle.uk/?rdbms=postgres_8.4&fiddle=1d47a59b33bbfae11ba3040f392ec9c5

【讨论】:

以上是关于仅在某些条件下使用 Redshift 中的 SQL 对具有相同名称的行进行分组的主要内容,如果未能解决你的问题,请参考以下文章

如何制作 Segue Pass 数据并且仅在满足某些条件时执行

如何根据 Where 条件获取 Redshift 中的上述值?

来自oracle sql的等效redshift sql

如何忽略错误但不跳过 redshift 复制命令中的行

ExtJS 仅在条件下显示 RowExpander

仅当表存在时如何删除 Amazon Redshift 中的表