fusionar dos COUNT en una consulta SQL

Aug 29 2020

Necesito hacer una consulta para mostrar new_customers X clients_cancellations

con esta consulta puedo obtener los nuevos_clientes por mes:

seleccione count(start_date), to_char(start_date, 'MM') como número de mes, to_char(start_date, 'YY') como número de año
del cliente donde start_date no es nulo
agrupar por to_char(start_date, 'MM'), to_char(start_date, 'YY')
ordenar por número de año, número de mes;

con este otro puedo sacar las cancelaciones de los clientes por mes:

seleccione count(cancellation_date), to_char(cancellation_date, 'MM') como número de mes, to_char(cancellation_date, 'YY') como número de año
del cliente donde cancel_date no es nulo
agrupar por to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
ordenar por número de año, número de mes;

ambas consultas devuelven algo como:

contar| número de mes | número de año
1 | 1 | 20
7 | 2 | 20
5 | 3 | 20

pero me gustaria algo como esto:

recuento_de_salidas_de_clientes|recuento_de_entradas_de_clientes| número de mes | número de año
 0 |1 | 1 | 20
 0 |7 | 2 | 20
 1 |0 | 3 | 20
 0 |1 | 4 | 20
 5 |7 | 5 | 20
 1 |5 | 6 | 20

Ya probé esta otra consulta:

seleccione 'start' como tipo, count(start_date) como count, to_char(start_date, 'MM') como monthNumber, to_char(start_date, 'YY') como yearNumber
del cliente donde start_date no es nulo
agrupar por to_char(start_date, 'MM'), to_char(start_date, 'YY')
Unión
seleccione 'cancelación' como tipo, cuente (fecha_de_cancelación) como cuenta, to_char(fecha_de_cancelación, 'MM') como número de mes, to_char(fecha_de cancelación, 'YY') como número de año
del cliente donde cancel_date no es nulo
agrupar por to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
ordenar por número de año, número de mes;

El resultado es "bien":

tipo |nueva cuenta | número de mes | número de año
 inicio |1 | 1 | 20
 cancelación |1 | 1 | 20
 cancelación |7 | 2 | 20
 empezar |3 | 3 | 20
 cancelación |1 | 4 | 20
 inicio |7 | 5 | 20
 inicio |5 | 6 | 20

Pero tendré que hacer algunas operaciones en el código para lograr lo que necesito.

¿Cómo puedo fusionar estas dos consultas en una? Estoy usando postgreslq.

Respuestas

1 GMB Aug 29 2020 at 06:30

Una opción quita el pivote de las filas y luego las agrega. En Postgres, expresaría esto con una unión lateral:

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