Amazon Redshift/PostgreSQL中的高效分组

Amazon Redshift/PostgreSQL中的高效分组,sql,postgresql,group-by,amazon-redshift,paraccel,Sql,Postgresql,Group By,Amazon Redshift,Paraccel,在分析处理中,通常需要将不重要的数据组折叠到结果表中的一行中。一种方法是通过CASE表达式进行分组,其中不重要的组通过CASE表达式合并成一行,返回单个值,例如,组为NULL。这个问题是关于在AmazonRedshift中执行此分组的有效方法,它基于ParAccel:close-Posgresql8.0的功能 作为一个例子,考虑一个按类型和一个表中的URL的组,其中每行是单个URL访问。目标是执行聚合,以便为url访问计数超过某个阈值的每种类型、url对发出一行,并为访问计数低于该阈值的所有类型

在分析处理中,通常需要将不重要的数据组折叠到结果表中的一行中。一种方法是通过CASE表达式进行分组,其中不重要的组通过CASE表达式合并成一行,返回单个值,例如,组为NULL。这个问题是关于在AmazonRedshift中执行此分组的有效方法,它基于ParAccel:close-Posgresql8.0的功能

作为一个例子,考虑一个按类型和一个表中的URL的组,其中每行是单个URL访问。目标是执行聚合,以便为url访问计数超过某个阈值的每种类型、url对发出一行,并为访问计数低于该阈值的所有类型、url对发出一个类型、NULL行。结果表中的其余列将具有基于此分组的总和/计数聚合

例如,以下数据

+------+----------------------+-----------------------+
| type | url                  | < 50+ other columns > |
+------+----------------------+-----------------------+
|  A   | http://popular.com   |                       |
|  A   | http://popular.com   |                       |
|  A   | < 9997 more times>   |                       |
|  A   | http://popular.com   |                       |
|  A   | http://small-one.com |                       |
|  B   | http://tiny.com      |                       |
|  B   | http://tiny-too.com  |                       |
进一步的测试表明,双重聚合可以展开为涉及每个独立CASE表达式的所有独立查询的联合。在这种特殊情况下,对于大约有2亿行的样本数据集,这种方法的执行速度始终快30%。然而,该结果是特定于模式和数据的

with temp_counts as (SELECT type, url, COUNT(*) as cnt FROM t GROUP BY type, url)
select * from temp_counts WHERE cnt >= 10000
UNION ALL
SELECT type, NULL as url, SUM(cnt) as cnt from temp_counts 
WHERE cnt < 10000 
GROUP BY type
这表明了在Amazon Redshift中实现和优化任意分离分组和摘要的两种通用模式。如果性能对您很重要,请对两者进行基准测试

首先,根据类型url分组。 然后第二次分组类型,当访问次数<10000,则为NULL else url。
我使用了SQL Server语法,我希望它也适用于Postgres。

您可以通过两个聚合来实现这一点:

select type, (case when cnt > XXX then url end) as url, sum(cnt) as visit_cnt
from (select type, url, count(*) as cnt
      from t
      group by type, url
     ) t
group by type, (case when cnt > XXX then url end)
order by type, sum(cnt) desc;

我在开始时也使用了此路径,但它生成了以下错误:执行SQL命令时发生错误:选择类型,当cnt>=10000时为case,然后url结束为url,sumcnt作为访问从选择类型开始,url。。。错误:t.cnt列必须出现在GROUP BY子句中,或用于聚合函数[SQL State=42803]我跟踪到了此特定功能的错误,在GROUP BY列中引用了亚马逊红移不支持的相关子查询的结果,并用信息更新了问题。@Sim。尝试使用组中的表达式的版本,因为我刚刚修改了它。嗯,如果我将嵌套的SELECT外部化为with子句,则上面的示例使用双重聚合,运行速度始终比两个SELECT的并集慢30%左右:一个是cnt>XXX,另一个是表单SELECT类型,url为NULL,来自temp_的SUMcnt计数,其中cntwith temp_counts as (SELECT type, url, COUNT(*) as cnt FROM t GROUP BY type, url) select * from temp_counts WHERE cnt >= 10000 UNION ALL SELECT type, NULL as url, SUM(cnt) as cnt from temp_counts WHERE cnt < 10000 GROUP BY type
select type, (case when cnt > XXX then url end) as url, sum(cnt) as visit_cnt
from (select type, url, count(*) as cnt
      from t
      group by type, url
     ) t
group by type, (case when cnt > XXX then url end)
order by type, sum(cnt) desc;