在一张桌子上比较两个多月之间客户的演变

Posted

技术标签:

【中文标题】在一张桌子上比较两个多月之间客户的演变【英文标题】:Compare evolution of clients between more than two month on a table 【发布时间】:2020-12-12 00:05:38 【问题描述】:

我有一个数据库,每月都会在其中输入新记录,我可以在其中查看每个提供商拥有的客户数量和客户名称。大约有 1500 家客户和 17 家供应商。可以禁用老年客户,也可以每月注册新客户。每个客户只能有一个提供商,但每个月他们都可以更换提供商。我正在尝试执行一个查询,返回每个月谁更改了提供者(客户的姓名、他们和谁在一起以及他们和谁在一起)。

我的查询中的所有内容都运行良好,但我希望它比较所有月份,而不仅仅是我在表 1 和表 2 上写的两个月。

我开发了以下代码:

WITH
-- CREATE TABLE 1 FROM A GENERAL DATABASE WITH CURRENT MONTH INFO
t1 AS (
  SELECT 
        Transaction_date,
        Provider,
        Customer_ID,
        Customer_Name,
        CONCAT(Customer_ID, Provider) AS ID1,
        Demand
    FROM MyDataBase
    WHERE YEAR(Transaction_date)=2020
    AND MONTH(Transaction_date)=10
), 

-- CREATE TABLE 2 FROM A GENERAL DATABASE WITH LAST MONTH INFO
t2 AS (
  SELECT 
        Transaction_date AS Transaction_date2,
        Provider AS Provider2,
        Customer_Code AS Customer_ID2,
        Customer_Name AS Customer_Name2,
        CONCAT(Customer_ID, Provider) AS ID2,
        Demand AS Demand2
    FROM MyDataBase
    WHERE YEAR(Transaction_date)=2020
    AND MONTH(Transaction_date)=09
    
),


-- t3: IDENTIFY WHO CHANGED

t3 AS (
    SELECT 
        Transaction_date2,
        Provider2,
        Customer_ID2,
        Customer_Name2,
        Demand2
    FROM t1
    RIGHT JOIN t2
    ON t2.ID2 = t1.ID1
    WHERE demand IS null
),

-- t4: RETURNS THE CUSTOMERS THAT CHANGED OF PRIVIDER IN AN ORGANIZED TABLE

T4 AS (
    SELECT 
        Transacion_date,
        Provider2 AS 'Last_Provider',   
        Provider AS 'Actual_Privder',
        Customer_ID,
        Customer_Name,
        Demand
    FROM t3
        LEFT JOIN t1
        ON t1.Customer_ID = t5.Customer_ID2
        WHERE Demand IS NOT NULL 
        AND Transacion_date IS NOT NULL
    )
    

SELECT * FROM t4

数据库样本

 Month        & Provider & Client & Demand \\
 2020-01-01   & A        & 1      & 50     \\
 2020-01-01   & A        & 2      & 40     \\
 2020-01-01   & B        & 3      & 55     \\
 2020-01-01   & B        & 4      & 70     \\
 2020-02-01   & A        & 1      & 55     \\
 2020-02-01   & B        & 2      & 34     \\
 2020-02-01   & B        & 3      & 67     \\
 2020-02-01   & B        & 4      & 89     \\
 2020-03-01   & A        & 1      & 78     \\
 2020-03-01   & A        & 2      & 89     \\
 2020-03-01   & A        & 3      & 76     \\
 2020-03-01   & B        & 4      & 45    

如您在示例中所见

1 月:有 4 个客户。 2 月:客户 #2 切换到供应商 B。 3 月:客户 #2 和 #3 被转移到提供商 A。

【问题讨论】:

【参考方案1】:

我正在尝试执行一个查询,返回每个月谁更改了提供者(客户的姓名、他们和谁在一起以及他们和谁在一起)。

如果您运行的是 mysql 8.0,则可以使用 lag() 获取每个客户的“以前的”提供者。然后剩下要做的就是过滤提供者更改的月份:

select *
from (
    select t.*,
        lag(provider) over(partition by customer_code order by transaction_date) as previous_provider
    from mytable t
) t
where provider <> previous_provider

在早期版本中,您可以使用子查询来模拟窗口函数:

select *
from (
    select t.*,
        (
            select t1.provider 
            from mytable t1 
            where t1.customer_code = t.customer_code and t1.transaction_date < t.transaction_date 
            order by t1.transaction_date desc limit 1
        ) as previous_provider
    from mytable t
) t
where provider <> previous_provider

【讨论】:

谢谢GMB,它工作得很好,查询的持续时间真的很快。

以上是关于在一张桌子上比较两个多月之间客户的演变的主要内容,如果未能解决你的问题,请参考以下文章

JAVA分布式架构的演变及解决方案

网站平台架构演变史 - 数据库表的查询优化

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

036 互联网的框架演变

框架演变

单机服务到分布式架构的演变,有了它,面试再也不慌了!