所以我在我的代码中有这个查询:
SELECT month, total_orders, first_orders, first_orders::numeric / total_orders::numeric * 100 AS ratio
FROM (
SELECT month, COUNT(1) AS total_orders
FROM (
SELECT DISTINCT date_trunc('month', date) AS month, email
FROM shop_orders
WHERE status_code = 'CONFIRMED'
) AS customers
GROUP BY month
) AS total_orders_my_month
LEFT JOIN (
SELECT month, COUNT(1) AS first_orders FROM (
SELECT email, date_trunc('month', MIN(date)) AS month
FROM shop_orders
WHERE status_code = 'CONFIRMED'
GROUP BY email
) AS first_orders_by_month
GROUP BY month
) AS first_orders_by_month2 USING (month)
ORDER BY month DESC
它的作用是以一种形式重新调整行:month |那个月的客户数量这个月的第一次客户数量首次购客的百分比
我需要的是每个月还能找到超过1个订单的客户数量。
所以我添加了这段代码:
LEFT JOIN (
SELECT month, COUNT(1) AS multiple_orders FROM (
SELECT email, date_trunc('month', MIN(date)) AS month
FROM shop_orders
WHERE status_code = 'CONFIRMED'
GROUP BY email HAVING COUNT(1) >=2
) AS multiple_orders_by_month
GROUP BY month
) AS multiple_orders_by_month2 USING (month)
然而,这仅返回首次订购客户而非所有客户的2个或更多订单的客户。有人可以帮忙吗?
注意:所有数据都在shop_orders表中,唯一客户由电子邮件字段标识,日期字段包含有关订单日期的信息。
我希望它清楚。
我对postgresql很新,所以有人指向正确的方向吗?感谢。
答案 0 :(得分:0)
我首先想指出的是,我是从纯SQL
路线而不是postsgresql
看这个,但理论基本相同。您的子查询SQL可能过于复杂,这是我正在研究如何创建查询:
首先,获取所有电子邮件地址的列表以及每月订购的订单数量;以下查询将返回分配给每封电子邮件的订单数量:
SELECT
month
, email
, COUNT(*)
FROM
shop_orders
WHERE
status_code = 'Confirmed'
GROUP BY
month
, email
这将每个月返回每个电子邮件地址的订单计数。然后,您可以使用HAVING
过滤器方法将此列表限制为每月包含多个电子邮件的所有电子邮件。
SELECT
month
, email
, COUNT(*) as ordersThisMonth
FROM
shop_orders
WHERE
status_code = 'Confirmed'
GROUP BY
month
, email
HAVING
COUNT(*) > 1
然后可以使用另一个聚合来访问此子查询,例如SUM(CASE WHEN ordersThisMonth > 1 THEN 1 ELSE 0 END)
,只有在收到多个订单时才会计算。我个人会尝试将您的查询简化为两个子查询,一个包含特定于month
的详细信息,另一个包含month
和email
的详细信息。
(以下代码未经语法检查,如前所述,我从纯粹的SQL角度来看这个。)
SELECT
month
, total_orders
, first_orders
/* Add together all firstMonthCount entries as it should only be 1 for the customers first month */
, SUM(firstMonthCount)::numeric / total_orders::numeric * 100 AS ratio
/* Count only e-mails which have more than one order for the month */
, SUM(CASE WHEN orderCount > 1 THEN 1 ELSE 0 END) AS multipleOrders
FROM
/*The following sub-query gets all the aggregates specific to a month */
( SELECT
date_trunc('month', date) AS month
, COUNT(1) AS total_orders
FROM
shop_orders
WHERE
status_code = 'CONFIRMED'
GROUP BY
month
) AS month_attributes
/*The following sub-query gets all the aggregates specific to a month AND e-mail */
LEFT JOIN (
SELECT
date_trunc('month', date) AS month
, email
, CASE WHEN date_trunc('month', date) = date_trunc('month', MIN(date)) THEN 1 ELSE 0 END AS firstMonthCount
, COUNT(*) AS orderCount
FROM
shop_orders
WHERE
status_code = 'CONFIRMED'
GROUP BY
month
,email
) AS email_month_attributes USING (month)
GROUP BY
month
希望上述有关HAVING
的查询和说明可以帮助您找到适合您目的的解决方案。我确信如果需要可读性/性能,可以进一步简化上述查询。