объединить два COUNT в один SQL-запрос

Aug 29 2020

Мне нужно сделать запрос, чтобы показать new_customers X customers_cancellations

с помощью этого запроса я могу получить new_customers по месяцам:

выберите count (start_date), to_char (start_date, 'MM') как monthNumber, to_char (start_date, 'YY') как yearNumber 
от клиента, где start_date не равно нулю 
группировать по to_char (start_date, 'MM'), to_char (start_date, 'YY') 
заказ по yearNumber, monthNumber;

с этим другим, я могу получать отмены клиентов по месяцам:

выберите count (cancellation_date), to_char (cancellation_date, 'MM') как monthNumber, to_char (cancellation_date, 'YY') как yearNumber
от клиента, где cancellation_date не равно нулю 
группа по to_char (cancellation_date, 'MM'), to_char (cancellation_date, 'YY') 
заказ по yearNumber, monthNumber;

оба запроса возвращают что-то вроде:

счет | номер месяца | номер года
1 | 1 | 20
7 | 2 | 20
5 | 3 | 20

но хотелось бы примерно такого:

customer_out_count | customer_in_count | номер месяца | номер года
 0 | 1 | 1 | 20
 0 | 7 | 2 | 20
 1 | 0 | 3 | 20
 0 | 1 | 4 | 20
 5 | 7 | 5 | 20
 1 | 5 | 6 | 20

Я уже пробовал этот другой запрос:

выберите start как тип, count (start_date) как count, to_char (start_date, 'MM') как monthNumber, to_char (start_date, 'YY') как yearNumber
от клиента, где start_date не равно нулю
группировать по to_char (start_date, 'MM'), to_char (start_date, 'YY')
союз
выберите "отмена" как тип, count (cancellation_date) как counta, to_char (cancellation_date, 'MM') как monthNumber, to_char (cancellation_date, 'YY') как yearNumber
от клиента, где cancellation_date не равно нулю
группа по to_char (cancellation_date, 'MM'), to_char (cancellation_date, 'YY')
заказ по yearNumber, monthNumber;

Результат "ок":

тип | newcount | номер месяца | номер года
 начало | 1 | 1 | 20
 отмена | 1 | 1 | 20
 отмена | 7 | 2 | 20
 начало | 3 | 3 | 20
 отмена | 1 | 4 | 20
 начало | 7 | 5 | 20
 начало | 5 | 6 | 20

Но мне нужно будет проделать некоторые операции с кодом, чтобы добиться того, что мне нужно.

Как я могу объединить эти два запроса в один? Я использую postgreslq.

Ответы

1 GMB Aug 29 2020 at 06:30

Один из вариантов: разворачивает строки, а затем объединяет их. В 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