2017-07-14 1 views
0

J'essaie de trouver une requête qui me donnera le nombre de clients qui ont traité avec 2 entités différentes dans le même mois. En d'autres termes, customer_ids qui a effectué des transactions avec company_a et company_b au cours du même mois. Voici ce que j'ai jusqu'à présent:Requête SQL pour le chevauchement d'ID de groupe (via la jointure interne) par mois

SELECT Extract(year FROM company_a_customers.transaction_date) 
     || Extract(month FROM company_a_customers.transaction_date) AS 
     payment_month, 
     Count(UNIQUE(company_a_customers.customer_id)) 
FROM (SELECT * 
     FROM my_table 
     WHERE (merchant_name LIKE '%company_a%')) AS company_a_customers 
     INNER JOIN (SELECT * 
        FROM my_table 
        WHERE (merchant_name = 'company_b')) AS 
        company_b_customers 
       ON company_a_customers.customer_id = 
        company_b_customers.customer_id 
GROUP BY Extract(year FROM company_a_customers.transaction_date) 
      || Extract(month FROM company_a_customers.transaction_date) 

Le problème est que cela me donne un total cumulé de tous les clients qui transigent avec la société A sur une base mensuelle par mois qui a également jamais traitées avec la société B.

Si je Whittle vers le bas pour un mois spécifique, il me donnera évidemment le chevauchement correct, parce que la requête ne reçoit que des ID pour ce mois:

SELECT Extract(year FROM company_a_customers.transaction_date) 
     || Extract(month FROM company_a_customers.transaction_date) AS 
     payment_month, 
     Count(UNIQUE(company_a_customers.customer_id)) 
FROM (SELECT * 
     FROM my_table 
     WHERE (merchant_name LIKE '%company_a%') 
       AND transaction_date >= '2017-06-01' 
       AND transaction_date <= '2017-06-30') AS company_a_customers 
     INNER JOIN (SELECT * 
        FROM my_table 
        WHERE (merchant_name = 'company_b') 
          AND transaction_date >= '2017-06-01' 
          AND transaction_date <= '2017-06-30') AS 
        company_b_customers 
       ON company_a_customers.customer_id = 
        company_b_customers.customer_id 
GROUP BY Extract(year FROM company_a_customers.transaction_date) 
      || Extract(month FROM company_a_customers.transaction_date) 

Comment puis-je faire cela dans un requête pour obtenir mensuelle totaux pour les clients qui ont effectué des transactions avec les deux sociétés au cours du mois donné?

Résultat souhaité: Sortie de la deuxième requête, mais pour chaque mois de la base de données. En d'autres termes:

Janvier 2017 xx, xxx clients se chevauchent Février 2017 xx, xxx clients se chevauchent Mars 2017 xx, xxx clients se chevauchent

de Merci beaucoup.

+0

Modifier votre question. (1) Marquer avec la base de données que vous utilisez. (2) Fournir des exemples de données. (3) Fournir les résultats souhaités. –

+0

J'ai fait les modifications suggérées –

Répondre

1

Vous pouvez tout simplement calculer année/mois pour les deux, puis l'ajouter comme condition_jointure, mais ce n'est pas très efficace car il pourrait créer un énorme résultat intermédiaire.

Il est préférable de vérifier chaque mois/client s'il y a eu des transactions avec les deux commerçants utilisant l'agrégation conditionnelle. Et puis compter par mois:

SELECT payment_month, count(*) 
FROM 
( SELECT Extract(year FROM transaction_date) 
      || Extract(month FROM transaction_date) AS payment_month, 
      customer_id 
    FROM my_table 
    WHERE (merchant_name LIKE '%company_a%') 
     OR (merchant_name = 'company_b') 
    GROUP BY payment_month, 
      customer_id 
    -- both merchants within the same months 
    HAVING SUM(CASE WHEN merchant_name LIKE '%company_a%' THEN 1 ELSE 0 END) > 0 
     AND SUM(CASE WHEN merchant_name = 'company_b' THEN 1 ELSE 0 END) > 0 
) AS dt 
GROUP BY 1 

Leur calcul est payment_month à compliquée (et la chaîne retournée est pas bien formaté).

Pour obtenir année/mois en tant que chaîne:

TO_CHAR(transaction_date, 'YYYYMM') 

comme numéro:

EXTRACT(YEAR FROM transaction_date) * 100 
+ EXTRACT(MONTH FROM transaction_date) 

ou calculer le premier du mois:

TRUNC(transaction_date, 'mon') 
1

Vous devriez pouvoir obtenir les résultats souhaités en une seule requête en comptant le nombre de merchant_names par mois et par identifiant client. Utiliser HAVING> 1 ne vous montrera que les clients ayant des transactions avec les deux (ou plus s'il y a plus de correspondances pour comme '% company_a%').

SELECT 
EXTRACT(Year from transaction_date)||EXTRACT(Month from transaction_date) as payment_month 
,customer_id 
,COUNT(DISTINCT merchant_name) as CompanyCount 
FROM my_table 
WHERE transaction_date >= '2017-06-01' AND transaction_date <= '2017-06-30' 
    AND (merchant_name = 'company_b' or merchant_name LIKE '%company_a%') 
GROUP BY 
    EXTRACT(Year from transaction_date)||EXTRACT(Month from transaction_date) 
,customer_id 
HAVING COUNT(DISTINCT merchant_name) > 1