【问题标题】:SQL Query to group ID overlap (via inner join) by monthSQL 查询按月分组 ID 重叠(通过内部联接)
【发布时间】:2017-07-15 03:29:16
【问题描述】:

我正在尝试查找一个查询,该查询将为我提供在同一个月内与 2 个不同实体进行交易的客户数量。也就是说,同月内与company_a 和company_b 交易的customer_ids。这是我目前所拥有的:

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) 

问题在于,这给了我按月与公司 A 进行交易的所有客户的总和,这些客户也曾经与公司 B 进行过交易。

如果我把它缩减到一个特定的月份,它显然会给我正确的重叠,因为查询只获取那个月的 ID:

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)

如何在一个查询中执行此操作,以获取在给定月份内与两家公司进行交易的客户的月度总计?

期望的结果:第二个查询的输出,但每个月都在数据库中。换句话说:

2017 年 1 月:xx,xxx 个重叠客户 2017 年 2 月:xx,xxx 重叠客户 2017 年 3 月:xx,xxx 重叠客户

非常感谢。

【问题讨论】:

  • 编辑您的问题。 (1) 使用您正在使用的数据库进行标记。 (2) 提供样本数据。 (3) 提供期望的结果。
  • 我已经进行了建议的修改

标签: sql teradata


【解决方案1】:

您可以简单地计算两者的年/月,然后将其添加为连接条件,但这不是很有效,因为它可能会产生巨大的中间结果。

您最好检查每个月/客户是否使用条件聚合与两个商家进行了交易。然后按月计算:

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

您的payment_month 计算过于复杂(并且返回的字符串格式不正确)。

以字符串形式获取年/月:

TO_CHAR(transaction_date, 'YYYYMM')

作为数字:

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

或计算月初:

TRUNC(transaction_date, 'mon')

【讨论】:

    【解决方案2】:

    您应该能够在一次查询中获得所需的结果,只需计算每个客户 ID 每月的商家名称数。使用 HAVING > 1 将只向您显示同时进行交易的客户(如果有更多匹配项,例如 '%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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-06
      • 2013-08-07
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      相关资源
      最近更新 更多