我正在构建一个使用多个with
语句计算某些子组的查询。我遇到问题的最终子查询是可能客户总数的总和。我正在创建一个比我真正构建的更简单的样本,所以请耐心等待。
基本上最终结果应如下所示:
请注意,它并不像将两列一起添加以获得总数那么简单。在这种情况下,客户可以,例如,离开组织,然后他们将不会计入总可能的客户。有一列指示客户何时进入该池,另一列指示客户离开的位置。所以我需要在每个给定的月份做一些事情,并考虑到这一点。 (基本上是select count(*) from customers where entry_date < [month being evaluated] and leave date !< [month being evaluated]
)。这就是我的问题所在,所以这就是我到目前为止所做的:
WITH customer_type1 AS
(
SELECT c1_visit_date, COUNT(*) AS c1_count
FROM (SELECT TO_CHAR(c.visit_time, 'MON YYYY') AS c1_visit_date
FROM customer c
where customer_type='1')
GROUP BY c1_visit_date;
),
customer_type2 AS
(
SELECT c2_visit_date, COUNT(*) as c2_count
FROM (SELECT TO_CHAR(c.visit_time, 'MON YYYY') AS c2_visit_date
FROM customer c
where customer_type='2')
GROUP BY c2_visit_date;
),
all_possible_customers AS
(
SELECT TO_DATE(customer_type1.c1_visit_date) AS APC_Date,
(
SELECT DISTINCT COUNT(c.customer_id)
FROM customer c
WHERE customer.start_date < APC_Date
AND (customer.end_date = NULL OR customer.end_date > APC_Date)
) AS all_possible_customer_count
FROM customer_type1;
)
SELECT customer_type1.c1_visit_date, customer_type1.c1_count, customer_type2.c2_count, all_possible_customers.all_possible_customer_count
FROM customer_type1
INNER JOIN customer_type1 ON customer_type1.c1_visit_date = customer_type2.c2_visit_date
INNER JOIN cusomter_type1 ON customer_type1.c1_visit_date = all_possible_customers.APC date;
但是我在第三个with
语句中遇到语法错误。 (当我清理它并运行前两个带有语句的CType1_visit和C.Type2_Visit时,它们工作正常。
我在第三个语句中遗漏了哪些内容,允许我按第一列对select语句进行分组?
答案 0 :(得分:1)
根据您发布的查询,我认为这就是您所追求的目标:
SELECT TRUNC(visit_date, 'mm') visit_date,
COUNT(CASE WHEN customer_type = '1' THEN 1 END) c1_count,
COUNT(CASE WHEN customer_type = '2' THEN 1 END) c2_count,
COUNT(CASE WHEN start_date < TRUNC(visit_date, 'mm') AND (end_date is null or end_date > TRUNC(visit_date, 'mm')) THEN 1 end) all_possible_customer_count
FROM customer
GROUP BY TRUNC(visit_date, 'mm');
然而,如果没有样本输入和预期的输出数据进行测试,很难说这是否接近你所追求的。
我对“所有可能的客户数量”的逻辑有点好奇 - 客户的访问日期是否超出了客户的开始和结束日期?此外,如果客户的开始和结束日期是2017年3月2日至20日,该怎么办?它们不会计入all_possible_customer_count,因为3月1日不在该范围内。
ETA,在考虑它之后,我很惊讶你的要求不是“在给定的日期范围内,找到类型1,类型2和在该范围内访问的任何类型的客户的数量” ,这将是:
SELECT TRUNC(visit_date, 'mm') visit_date,
COUNT(CASE WHEN customer_type = '1' THEN 1 END) c1_count,
COUNT(CASE WHEN customer_type = '2' THEN 1 END) c2_count,
COUNT(*) all_possible_customer_count
FROM customer
where start_date <= :end_of_date_range
and end_date >= :start_of_date_range
GROUP BY TRUNC(visit_date, 'mm');
可能有一个额外的谓词and visit_date between start_date and end_date
(假设日期中没有时间元素)。