将两个 COUNT 合并到一个 SQL 查询中
merge two COUNT in one SQL query
我需要做一个查询来显示 new_customers X customers_cancellations
通过此查询,我可以按月获得 new_customers:
select count(start_date), to_char(start_date, 'MM') as monthNumber, to_char(start_date, 'YY') as yearNumber
from customer where start_date is not null
group by to_char(start_date, 'MM'), to_char(start_date, 'YY')
order by yearNumber, monthNumber;
有了这个,我可以让客户按月取消订单:
select count(cancellation_date), to_char(cancellation_date, 'MM') as monthNumber, to_char(cancellation_date, 'YY') as yearNumber
from customer where cancellation_date is not null
group by to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
order by yearNumber, monthNumber;
这两个查询 return 类似于:
count| monthnumber |yearnumber
1 | 1 | 20
7 | 2 | 20
5 | 3 | 20
但我想要这样的东西:
customer_out_count|customer_in_count| monthnumber |yearnumber
0 |1 | 1 | 20
0 |7 | 2 | 20
1 |0 | 3 | 20
0 |1 | 4 | 20
5 |7 | 5 | 20
1 |5 | 6 | 20
我已经尝试过这个查询:
select 'start' as type, count(start_date) as count, to_char(start_date, 'MM') as monthNumber, to_char(start_date, 'YY') as yearNumber
from customer where start_date is not null
group by to_char(start_date, 'MM'), to_char(start_date, 'YY')
union
select 'cancellation' as type, count(cancellation_date) as counta, to_char(cancellation_date, 'MM') as monthNumber, to_char(cancellation_date, 'YY') as yearNumber
from customer where cancellation_date is not null
group by to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
order by yearNumber, monthNumber;
结果是“ok”:
type |newcount | monthnumber |yearnumber
start |1 | 1 | 20
cancellation |1 | 1 | 20
cancellation |7 | 2 | 20
start |3 | 3 | 20
cancellation |1 | 4 | 20
start |7 | 5 | 20
start |5 | 6 | 20
但我需要对代码进行一些操作才能实现我所需要的。
如何将这两个查询合并为一个?我正在使用 postgreslq。
一个选项将行反透视,然后聚合。在 Postgres 中,您可以使用横向连接来表达:
select
sum(x.customer_in_count) as customer_in_count,
sum(x.customer_out_count) as customer_out_count
to_char(x.dt, 'MM') as monthNumber,
to_char(x.dt, 'YY') as yearNumber
from customer c
cross join lateral (values
(c.start_date, 1, 0), (c.cancellation_date, 0, 1)
) as x(dt, customer_in_count, customer_out_count)
where x.dt is not null
group by monthNumber, yearNumber
order by monthNumber, yearNumber
我需要做一个查询来显示 new_customers X customers_cancellations
通过此查询,我可以按月获得 new_customers:
select count(start_date), to_char(start_date, 'MM') as monthNumber, to_char(start_date, 'YY') as yearNumber from customer where start_date is not null group by to_char(start_date, 'MM'), to_char(start_date, 'YY') order by yearNumber, monthNumber;
有了这个,我可以让客户按月取消订单:
select count(cancellation_date), to_char(cancellation_date, 'MM') as monthNumber, to_char(cancellation_date, 'YY') as yearNumber from customer where cancellation_date is not null group by to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY') order by yearNumber, monthNumber;
这两个查询 return 类似于:
count| monthnumber |yearnumber 1 | 1 | 20 7 | 2 | 20 5 | 3 | 20
但我想要这样的东西:
customer_out_count|customer_in_count| monthnumber |yearnumber 0 |1 | 1 | 20 0 |7 | 2 | 20 1 |0 | 3 | 20 0 |1 | 4 | 20 5 |7 | 5 | 20 1 |5 | 6 | 20
我已经尝试过这个查询:
select 'start' as type, count(start_date) as count, to_char(start_date, 'MM') as monthNumber, to_char(start_date, 'YY') as yearNumber from customer where start_date is not null group by to_char(start_date, 'MM'), to_char(start_date, 'YY') union select 'cancellation' as type, count(cancellation_date) as counta, to_char(cancellation_date, 'MM') as monthNumber, to_char(cancellation_date, 'YY') as yearNumber from customer where cancellation_date is not null group by to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY') order by yearNumber, monthNumber;
结果是“ok”:
type |newcount | monthnumber |yearnumber start |1 | 1 | 20 cancellation |1 | 1 | 20 cancellation |7 | 2 | 20 start |3 | 3 | 20 cancellation |1 | 4 | 20 start |7 | 5 | 20 start |5 | 6 | 20
但我需要对代码进行一些操作才能实现我所需要的。
如何将这两个查询合并为一个?我正在使用 postgreslq。
一个选项将行反透视,然后聚合。在 Postgres 中,您可以使用横向连接来表达:
select
sum(x.customer_in_count) as customer_in_count,
sum(x.customer_out_count) as customer_out_count
to_char(x.dt, 'MM') as monthNumber,
to_char(x.dt, 'YY') as yearNumber
from customer c
cross join lateral (values
(c.start_date, 1, 0), (c.cancellation_date, 0, 1)
) as x(dt, customer_in_count, customer_out_count)
where x.dt is not null
group by monthNumber, yearNumber
order by monthNumber, yearNumber