按内部联接发现的最早日期计算?

时间:2015-10-01 15:35:12

标签: postgresql

我有两个表,customerusermap和用户。每当用户注册我们的产品时,他们会立即被添加到一个名为users的表中,但直到他们开始为用户付费才会将他们添加到名为customerusermap的表中。

users表如下所示:

id    | customer_id        | firstname | lastname | created_at
-------------------------------------------------------
1725  | cus_3hEmhErE2jbwsO | Abby      | Smith    | 2015-03-19
1726  | cus_7oNweUrE4jbwr2 | Sam       | Peters   | 2015-06-20

customerusermap表如下所示:

customer_id        | user_id | created_at
------------------------------------------
cus_3hEmhErE2jbwsO | 9275    | 2015-09-01
cus_3hEmhErE2jbwsO | 2628    | 2015-09-05
cus_3hEmhErE2jbwsO | 2358    | 2015-07-05
cus_3hEmhErE2jbwsO | 3158    | 2015-08-05
cus_3hEmhErE2jbwsO | 2487    | 2015-08-05
cus_3hEmhErE2jbwsO | 6044    | 2015-08-05
cus_7oNweUrE4jbwr2 | 8094    | 2015-08-25
cus_7oNweUrE4jbwr2 | 2345    | 2015-09-02

在此示例中,Abby(cus_3hEmhErE2jbwsO)正在为6个用户付费。她开始为用户2358 2015-07-05付款,所以她应该被视为付费客户07-2015,而不是03-2015。 Sam正在支付2个用户,他开始在08-2015支付用户8094,所以他被认为是08-2015的付费客户,而不是06-2015。我有一个查询,每个月按付费客户的数量来抓取和分组:

SELECT concat(extract(MONTH from u.created_at),'-',extract(year from u.created_at)) as "Month", 
COUNT(distinct u.email) as "Total AB Paying Customers"
FROM customerusermap AS cm, users AS u
WHERE cm.customer_id=u.customer_id AND cm.user_id <> u.id
GROUP BY 1,extract(month from u.created_at),extract(year from u.created_at)
ORDER BY extract(year from u.created_at),extract(month from u.created_at);

但是这会抓住并计算客户被添加到用户表的日期,而不是他们实际开始支付的日期。我如何获取计数以便抓取customerusermap表中最早的日期?在这个例子中,所需的输出应该是:

Month    | Total AB Paying Customers
-------------------------------------
07-2015  | 1
08-2015  | 1

1 个答案:

答案 0 :(得分:1)

您可以使用以下查询:

SELECT CONCAT(EXTRACT(MONTH FROM startedPayingDate), '-', 
              EXTRACT(YEAR FROM startedPayingDate)) AS "Month", 
       COUNT(*) AS "Total AB Paying Customers"
FROM (       
   SELECT customer_id, MIN(created_at) AS startedPayingDate 
   FROM customerusermap AS cm
   WHERE NOT EXISTS (SELECT 1
                     FROM users AS u
                     WHERE cm.user_id = u.id)
   GROUP BY customer_id ) AS t
GROUP BY 1   

我使用NOT EXISTS运算符排除与“为自己付费”客户相关的记录(如果这是您的意图)。

MIN(created_at)customer_id日期后,您可以轻松计算外部查询中的每个日期。

Demo here