有什么方法可以加快此查询以捕获客户信息吗?有没有更好的方法来处理这些数据?

时间:2019-06-05 15:48:49

标签: sql sql-server tsql

我的查询时间很长,但我会尝试将其分解为几个部分。

首先,有变量,

DECLARE @LocalCompanyCode VARCHAR(5)
SET @LocalCompanyCode = '09'

DECLARE @LocalDivisionCode VARCHAR(5)
SET @LocalDivisionCode = '001'

DECLARE @CustomerBaseFromDate DATETIME --CustomerBase
SET @CustomerBaseFromDate = '1/1/2019'

DECLARE @CustomerBaseToDate DATETIME
SET @CustomerBaseToDate = '5/30/2019'

DECLARE @RecurringBaseFromDate DATETIME --Recurring Base
SET @RecurringBaseFromDate = '1/1/2018'

DECLARE @RecurringBaseToDate DATETIME
SET @RecurringBaseToDate = '1/1/2019'

DECLARE @LifetimeBaseFromDate DATETIME --Lifetime Base
SET @LifetimeBaseFromDate = '1/1/2015'

DECLARE @LifetimeBaseToDate DATETIME
SET @LifetimeBaseToDate = '1/1/2018'

公司代码和部门代码选择我们要为此查询运行的公司。客户群将是我们将要寻找的客户群。因此,在我们的示例中,是过去5个月。

因此,对于过去5个月中的所有客户,我们将使用“经常性收入基础”。这是模块化的,因此我们可以控制在考虑客户“丢失”之前的时间。我们将与定期客户进行比较,查看有多少客户是新客户,他们仅在该客户和定期客户基础上订购一次,以及有多少客户是定期客户,那些客户在这些期间内多次订购。

然后,我们还将拥有我们的终生基础。我们将检查在整个生命周期中订购一次或多次,未在经常性订购中订购但在5个月的客户基础中再次订购的客户。这样可以计算出有多少客户被“重新激活”或被认为丢失了,但是最近又与我们一起购买了。

然后我声明四个表

DECLARE @FullBase TABLE
    (
        Date_Created DATE,
        Company_Code VARCHAR(2),
        Division_Code VARCHAR(3),
        Invoice_Number VARCHAR(50),
        CUST_PO VARCHAR(50),
        Total_Quantity NUMERIC,
        TotalPrice MONEY,
        City VARCHAR(50),
        State VARCHAR(50),
        Zip VARCHAR(50),
        CountryCode VARCHAR(50),
        Month NUMERIC,
        CustomerEmail VARCHAR(MAX),
        OrderCountBase NUMERIC,
        TotalOrdersBase NUMERIC
    )

DECLARE @LifetimeBase TABLE
    (
        Date_Created DATE,
        Company_Code VARCHAR(2),
        Division_Code VARCHAR(3),
        Invoice_Number VARCHAR(50),
        CUST_PO VARCHAR(50),
        Total_Quantity NUMERIC,
        TotalPrice MONEY,
        City VARCHAR(50),
        State VARCHAR(50),
        Zip VARCHAR(50),
        CountryCode VARCHAR(50),
        Month NUMERIC,
        CustomerEmail VARCHAR(MAX),
        OrderCountLifetimeBase NUMERIC,
        TotalOrdersLifetimeBase NUMERIC
    )

DECLARE @RecurringBase TABLE
    (
        Date_Created DATE,
        Company_Code VARCHAR(2),
        Division_Code VARCHAR(3),
        Invoice_Number VARCHAR(50),
        CUST_PO VARCHAR(50),
        Total_Quantity NUMERIC,
        TotalPrice MONEY,
        City VARCHAR(50),
        State VARCHAR(50),
        Zip VARCHAR(50),
        CountryCode VARCHAR(50),
        Month NUMERIC,
        CustomerEmail VARCHAR(MAX),
        OrderCountRecurringBase NUMERIC,
        TotalOrdersRecurringBase NUMERIC
    )

DECLARE @CustomerBase TABLE
    (
        Date_Created DATE,
        Company_Code VARCHAR(2),
        Division_Code VARCHAR(3),
        Invoice_Number VARCHAR(50),
        CUST_PO VARCHAR(50),
        Total_Quantity NUMERIC,
        TotalPrice MONEY,
        City VARCHAR(50),
        State VARCHAR(50),
        Zip VARCHAR(50),
        CountryCode VARCHAR(50),
        Month NUMERIC,
        CustomerEmail VARCHAR(MAX),
        OrderCountCustomerBase NUMERIC,
        TotalOrdersCustomerBase NUMERIC
    )

然后,从生命周期库的开始到客户库的末尾,我将所有客户插入“ FullBase”中

INSERT INTO @FullBase
        SELECT  Orders.Date_Created
                ,Orders.Company_Code
                ,Orders.Division_Code
                ,Orders.Invoice_Number
                ,Orders.CUST_PO
                ,Orders.Total_Quantity
                ,Orders.Total
                ,Orders.City
                ,Orders.State
                ,Orders.Zip
                ,Orders.CountryCode
                ,Orders.Month
                ,Orders.CustomerEmail

                ,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountBase
                ,Count(*) over (partition by CustomerEmail) TotalOrdersBase

            FROM(
                Select
                    CONVERT(Date, OrderCreated) Date_Created
                    ,CONCAT ('0', LEFT(OrderName,1)) Company_Code
                    ,CONCAT ('00', RIGHT(LEFT(OrderName,2),1)) Division_Code
                    ,InvoiceNumber Invoice_Number
                    ,OrderName CUST_PO
                    ,1 Total_Quantity
                    ,TotalPrice Total
                    ,ShippingCity City
                    ,CASE WHEN ShippingCountryCode <> 'US' THEN 'INT' ELSE ShippingProvinceCode END State
                    ,ShippingZip Zip
                    ,ShippingCountryCode CountryCode
                    ,Month( OrderCreated) Month
                    ,Email CustomerEmail
                From [SHOPIFY].[shopify_moret].[dbo].orderwrappers O
                Where CONVERT(Date, O.OrderCreated) >= Convert(datetime, '05/29/2019')
                AND CONCAT ('0', LEFT(O.OrderName,1)) = @LocalCompanyCode--'09'
                AND CONCAT ('00', RIGHT(LEFT(O.OrderName,2),1)) = @LocalDivisionCode --'001'
            UNION
                Select
                    Archive.Date_Created
                    ,Archive.Company_Code
                    ,Archive.Division_Code
                    ,Archive.Invoice_Number
                    ,('91'+Archive.CUST_PO) CUST_PO
                    ,Archive.Total_Quantity
                    ,Archive.Total
                    ,Archive.City
                    ,Archive.State
                    ,Archive.Zip
                    ,Archive.Country
                    ,Archive.Month
                    ,Archive.CustomerEmail
                FROM SpraygroundArchivedOrders Archive
                Where Archive.Date_Created < Convert(datetime, '05/29/2019')
            ) Orders
            Where Orders.Date_Created BETWEEN @LifetimeBaseFromDate AND @CustomerBaseToDate

以下是数据外观的示例:

https://docs.google.com/spreadsheets/d/1wnjVHcPHHnugywa7Qz-aqctaD4cDI5DxehNna0TyaFU/edit?usp=sharing

然后,我使用这个完整的基数,以其他三个表中的顺序填充它们。

INSERT INTO @LifetimeBase
    SELECT 
         F.Date_Created
        ,F.Company_Code
        ,F.Division_Code
        ,F.Invoice_Number
        ,F.CUST_PO
        ,F.Total_Quantity
        ,F.TotalPrice
        ,F.City
        ,F.State
        ,F.Zip
        ,F.CountryCode
        ,F.Month
        ,F.CustomerEmail
        ,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountLifetimeBase
        ,Count(*) over (partition by CustomerEmail) TotalOrdersLifetimeBase
    FROM @FullBase F
    Where F.Date_Created BETWEEN @LifetimeBaseFromDate AND @LifetimeBaseToDate 

    INSERT INTO @RecurringBase
    SELECT 
         F.Date_Created
        ,F.Company_Code
        ,F.Division_Code
        ,F.Invoice_Number
        ,F.CUST_PO
        ,F.Total_Quantity
        ,F.TotalPrice
        ,F.City
        ,F.State
        ,F.Zip
        ,F.CountryCode
        ,F.Month
        ,F.CustomerEmail
        ,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountRecurringBase
        ,Count(*) over (partition by CustomerEmail) TotalOrdersRecurringBase
    FROM @FullBase F
    Where F.Date_Created BETWEEN @RecurringBaseFromDate AND @RecurringBaseToDate 

    INSERT INTO @CustomerBase
    SELECT 
         F.Date_Created
        ,F.Company_Code
        ,F.Division_Code
        ,F.Invoice_Number
        ,F.CUST_PO
        ,F.Total_Quantity
        ,F.TotalPrice
        ,F.City
        ,F.State
        ,F.Zip
        ,F.CountryCode
        ,F.Month
        ,F.CustomerEmail
        ,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountCustomerBase
        ,Count(*) over (partition by CustomerEmail) TotalOrdersCustomerBase
    FROM @FullBase F
    Where F.Date_Created BETWEEN @CustomerBaseFromDate AND @CustomerBaseToDate 

如果我仅从一个基数(包括完整基数)中选择*,则查询仅需花费几秒钟即可运行,并返回所有客户订单的140,000行(对于@FullBase)。

但是,此查询的最后一部分,即运行的部分,对于我6个月的客户来说需要10分钟才能运行

SELECT 
    CC.CustomerEmail
    ,CC.TotalOrdersCustomerBase
    ,RC.TotalOrdersRecurringBase
    ,LC.TotalOrdersLifetimeBase
    From
    (
    SELECT DISTINCT
        C.CustomerEmail
        ,C.TotalOrdersCustomerBase
        FROM
        @CustomerBase C
    ) CC
    LEFT JOIN 
    (
        SELECT DISTINCT
        R.CustomerEmail
        ,R.TotalOrdersRecurringBase
        FROM
        @RecurringBase R
    ) RC ON CC.CustomerEmail = RC.CustomerEmail

    LEFT JOIN 
    (
        SELECT DISTINCT
        L.CustomerEmail
        ,L.TotalOrdersLifetimeBase
        FROM
        @LifetimeBase L
    ) LC ON CC.CustomerEmail = LC.CustomerEmail

有人对我有什么建议吗?有什么更好的方法吗?

0 个答案:

没有答案