fusionner deux COUNT dans une requête SQL

Aug 29 2020

Je dois faire une requête pour afficher new_customers X customers_cancellations

avec cette requête, je peux obtenir les new_customers par mois :

sélectionnez count(start_date), to_char(start_date, 'MM') comme monthNumber, to_char(start_date, 'YY') comme yearNumber
du client où start_date n'est pas nul
grouper par to_char(start_date, 'MM'), to_char(start_date, 'YY')
trier par annéeNuméro, moisNuméro ;

avec cet autre, je peux obtenir les annulations des clients par mois :

sélectionnez count(cancellation_date), to_char(cancellation_date, 'MM') comme monthNumber, to_char(cancellation_date, 'YY') comme yearNumber
du client où l'annulation_date n'est pas nulle
grouper par to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
trier par annéeNuméro, moisNuméro ;

les deux requêtes renvoient quelque chose comme :

compter | numéromois |numéroannée
1 | 1 | 20
7 | 2 | 20
5 | 3 | 20

mais je voudrais quelque chose comme ça:

customer_out_count|client_in_count| numéromois |numéroannée
 0 |1 | 1 | 20
 0 |7 | 2 | 20
 1 |0 | 3 | 20
 0 |1 | 4 | 20
 5 |7 | 5 | 20
 1 |5 | 6 | 20

J'ai déjà essayé cette autre requête :

sélectionnez 'start' comme type, count(start_date) comme count, to_char(start_date, 'MM') comme monthNumber, to_char(start_date, 'YY') comme yearNumber
du client où start_date n'est pas nul
grouper par to_char(start_date, 'MM'), to_char(start_date, 'YY')
syndicat
sélectionnez 'annulation' comme type, count(cancellation_date) comme counta, to_char(cancellation_date, 'MM') comme monthNumber, to_char(cancellation_date, 'YY') comme yearNumber
du client où l'annulation_date n'est pas nulle
grouper par to_char(cancellation_date, 'MM'), to_char(cancellation_date, 'YY')
trier par annéeNuméro, moisNuméro ;

Le résultat c'est "ok":

tapez |nouveaucompte | numéromois |numéroannée
 démarrer |1 | 1 | 20
 annulation |1 | 1 | 20
 annulation |7 | 2 | 20
 démarrer |3 | 3 | 20
 annulation |1 | 4 | 20
 démarrer |7 | 5 | 20
 démarrer |5 | 6 | 20

Mais je devrai faire quelques opérations sur le code pour obtenir ce dont j'ai besoin.

Comment puis-je fusionner ces deux requêtes en une seule? J'utilise postgreslq.

Réponses

1 GMB Aug 29 2020 at 06:30

Une option annule le pivot des lignes, puis les agrège. Dans Postgres, vous exprimeriez cela avec une jointure latérale :

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