范围内每个数字的 SQL 计数总计(编辑:通过 UDF)
Posted
技术标签:
【中文标题】范围内每个数字的 SQL 计数总计(编辑:通过 UDF)【英文标题】:SQL count totals for each number in a range (Edit: via a UDF) 【发布时间】:2015-07-25 05:37:05 【问题描述】:我在 Amazon (AWS) RedShift 中有类似以下的数据,它代表了不同人的阅读日志,每一行都是特定日期阅读的章节跨度的记录:
| person | date | book | chapter_start | chapter_end |
|--------|--------|----------|---------------|-------------|
| Alice | 7/1/15 | Big Red | 4 | 7 |
| Bob | 7/1/15 | Big Red | 1 | 5 |
| James | 7/1/15 | Big Red | 2 | 9 |
| Tim | 7/1/15 | Big Red | 10 | 12 |
| Alice | 7/2/15 | Big Red | 8 | 10 |
| Bob | 7/2/15 | Big Red | 6 | 8 |
| James | 7/2/15 | Big Red | 10 | 11 |
| Tim | 7/1/15 | Blue Sky | 1 | 3 |
| Alice | 7/1/15 | Blue Sky | 3 | 4 |
我想知道是否有一个 SQL 查询(记住它需要与 RedShift 兼容的 postgresql)可以为跨度中的每一章产生一个计数,以便结果如下所示:
| book | chapter | count |
|----------|---------|-------|
| Big Red | 1 | 1 |
| Big Red | 2 | 2 |
| Big Red | 3 | 2 |
| Big Red | 4 | 3 |
| Big Red | 5 | 3 |
| Big Red | 6 | 3 |
| Big Red | 7 | 3 |
| Big Red | 8 | 3 |
| Big Red | 9 | 2 |
| Big Red | 10 | 3 |
| Big Red | 11 | 2 |
| Big Red | 12 | 1 |
| Blue Sky | 1 | 1 |
| Blue Sky | 2 | 1 |
| Blue Sky | 3 | 2 |
| Blue Sky | 4 | 2 |
请注意,在上面的结果中,计数不仅仅考虑了 chapter_start 和 chapter_end。例如,如果我们处理 Tim 从第 1 章到第 3 章读取 Blue Sky 的条目,则 Blue Sky 的第 1、2 和 3 章应该增加各自的计数器。
编辑(2015 年 7 月 28 日):经过进一步研究,似乎 Mureinik 的以下建议适用于完全符合 postgresql 的系统,但 RedShift 仅支持一小部分 postgresql 函数(请参阅: Unsupported PostgeSQL Functions in RedShift) 因此他的回答不适用于 RedShift。目前,这似乎也无法通过用户定义函数 (UDF) 实现,因为它们也不支持。令人鼓舞的一点是,RedShift 产品经理确认他们计划在 2015 年 9 月之前支持符合 postgresql 的 UDF。>
如上所述,是否有人愿意通过 UDF 承担相当于 GENERATE_SERIES() 的任务?
编辑(2015 年 9 月 11 日): UDF 终于在 RedShift 中可用。请参阅新发布的AWS RedShift UDF documentation。澄清需求——需要的是 python 中的一个集合返回函数,它复制了Postgres GENERATE_SERIES() function 的功能。有人愿意挑战吗?
编辑(2016 年 1 月 8 日):在与 AWS 反复讨论并对其文档进行一些澄清后,RedShift 中支持的 UDF 似乎只能返回单个值,而不是一组.因此,目前似乎不可能创建一个模仿此功能的 UDF。
【问题讨论】:
【参考方案1】:您可以使用generate_series
创建chapter_start
和chapter_end
之间所有章节的列表,然后按它们分组并计数:
SELECT book, chapter, COUNT(*)
FROM (SELECT book, GENERATE_SERIES(chapter_start, chapter_end) AS chapter
FROM mytable) t
GROUP BY book, chapter
【讨论】:
Mureinik,您的解决方案在 postresql 中运行良好,但在 RedShift 集群上执行时失败,并出现错误:“Redshift 表不支持指定的类型或函数(每个 INFO 消息一个)”。这很令人失望,因为 SELECT * FROM generate_series(2,4); 的简单测试它确实在我的 RedShift 集群上正确执行。结果 GENERATE_SERIES() 在 RedShift (docs.aws.amazon.com/redshift/latest/dg/…) 的不支持函数列表中。还有其他建议吗?以上是关于范围内每个数字的 SQL 计数总计(编辑:通过 UDF)的主要内容,如果未能解决你的问题,请参考以下文章
SQL 使用 group_concat 与每个连接项目的计数,而不是在一行中的总计数