我有两个表points
和contacts
,我试图按月将每个联系人的平均points.score
分组。 注意点数和联系人不相关,我只想要一个月内创建的点数之和除以该月份存在的联系人数量。
所以,我需要总结按created_at月份分组的点数,我需要只接受那个月的联系人数量。这是最后一部分让我烦恼的部分。我不确定如何在子查询中使用外部查询中的列。我试过这样的事情:
SELECT SUM(score) AS points_sum,
EXTRACT(month FROM created_at) AS month,
date_trunc('MONTH', created_at) + INTERVAL '1 month' AS next_month,
(SELECT COUNT(id) FROM contacts WHERE contacts.created_at <= next_month) as contact_count
FROM points
GROUP BY month, next_month
ORDER BY month
所以,我正在提取我的积分总和的实际月份,同时,得到next_month的开头,这样我就可以说“让我计算他们创建的联系人的数量&lt; next_month“
但它抱怨column next_month doesn't exist
这是可以理解的,因为子查询对外部查询一无所知。使用points.next_month
进行资格认证也不起作用。
那么有人能指出我如何实现这个目标的正确方向吗?
点
score | created_at
10 | "2011-11-15 21:44:00.363423"
11 | "2011-10-15 21:44:00.69667"
12 | "2011-09-15 21:44:00.773289"
13 | "2011-08-15 21:44:00.848838"
14 | "2011-07-15 21:44:00.924152"
联系人
id | created_at
6 | "2011-07-15 21:43:17.534777"
5 | "2011-08-15 21:43:17.520828"
4 | "2011-09-15 21:43:17.506452"
3 | "2011-10-15 21:43:17.491848"
1 | "2011-11-15 21:42:54.759225"
sum,month和next_month(没有subselect)
sum | month | next_month
14 | 7 | "2011-08-01 00:00:00"
13 | 8 | "2011-09-01 00:00:00"
12 | 9 | "2011-10-01 00:00:00"
11 | 10 | "2011-11-01 00:00:00"
10 | 11 | "2011-12-01 00:00:00"
答案 0 :(得分:10)
现在有运行总和的联系人。我的第一稿每月使用新联系人,这显然不是OP想要的。
WITH c AS (
SELECT created_at
,count(id) OVER (order BY created_at) AS ct
FROM contacts
), p AS (
SELECT date_trunc('month', created_at) AS month
,sum(score) AS points_sum
FROM points
GROUP BY 1
)
SELECT p.month
,EXTRACT(month FROM p.month) AS month_nr
,p.points_sum
,( SELECT c.ct
FROM c
WHERE c.created_at < (p.month + interval '1 month')
ORDER BY c.created_at DESC
LIMIT 1) AS contacts
FROM p
ORDER BY 1
points
中没有缺少月份。如果您想要所有月份(包括points
中的遗失月份),请生成一个包含generate_series()并且LEFT JOIN的月份列表。您的原始查询形式可以这样工作:
SELECT month
,EXTRACT(month FROM month) AS month_nr
,points_sum
,(SELECT count(*)
FROM contacts c
WHERE c.created_at < (p.month + interval '1 month')) AS contact_count
FROM (
SELECT date_trunc('MONTH', created_at) AS month
,sum(score) AS points_sum
FROM points p
GROUP BY 1
) p
ORDER BY 1
修复错误的直接原因是将聚合放入子查询中。你以一种不可能的方式混合水平
我希望我的变体在大桌子上稍快一些。关于较小的表不确定。如果你用测试结果报告,那就太好了
另外还有一个小修复:<
而不是<=
。