一个范围内每个数字的SQL计数总计(编辑:通过UDF)

时间:2015-07-25 05:37:05

标签: python sql postgresql select amazon-redshift

我在亚马逊(AWS)RedShift中拥有类似于以下内容的数据,它代表了各种人的阅读日志,每行都记录了特定日子内阅读的章节范围:

let dict: NSDictionary = [0: ["source": [3: "result"]]]

dict[0]?["source"]??[3] // returns nil (surprise!)
dict[0]?["source"]??[3 as NSNumber] // returns "result"

let dict2: NSDictionary = [0: ["source": [8, 7, 6, 5, 4]]]

dict2[0]?["source"]??[3] // returns 5
dict2[0]?["source"]??[3 as NSNumber] // returns nil (surprise!)

我想知道是否有一个SQL查询(请记住它需要与RedShift兼容的postgresql),它可以为跨度中的每个章节生成一个计数,以便结果如下所示:

| 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           | 

请注意,在上面的结果中,计数不仅仅是在考虑chapter_start和chapter_end。例如,如果我们处理蒂姆从第1章到第3章读蓝天的条目,蓝天的第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中的set return函数,它复制了Postgres GENERATE_SERIES() function的功能。有人接受挑战吗?

编辑(2016年1月8日):经过AWS的一些来回及其文档的澄清后,RedShift支持的UDF似乎只能返回单个值,不是一套。因此,目前似乎无法创建模仿此功能的UDF。

1 个答案:

答案 0 :(得分:3)

您可以使用generate_series创建chapter_startchapter_end之间所有章节的列表,然后按其分组并计算:

SELECT   book, chapter, COUNT(*)
FROM     (SELECT book, GENERATE_SERIES(chapter_start, chapter_end) AS chapter
          FROM   mytable) t
GROUP BY book, chapter