SQL:使用分层(相关)客户评估新客户类型或现有客户类型

时间:2016-05-26 15:14:10

标签: sql sql-server

我需要一种更有效的方法来评估客户是新用户还是现有用户。 新客户的标准:

  • 客户或任何相关客户未在开始日期和结束日期之间下订单

我写了一个函数来做这个,但它很有效,但它很慢。我们有分层的客户,包括孩子,父母,...终极父母。我的功能是通过获取任何给定客户的最终父母,选择其所有子项,然后评估属于任何这些子项的订单是否存在于开始日期和结束日期之间的订单表中。

该函数为新客户返回1(True)或为现有客户返回0(False)。

有更有效的方法吗?在调用~3k记录时,我的功能大约需要20分钟。

功能:

set ansi_nulls on
go
set quoted_identifier on
go

create function dbo.is_new_customer (
@ultimate_parent_number nvarchar(255),
@existing_customer_begin_date date,
@existing_customer_end_date date
)
returns int
as
begin
declare @return int

set @return = (
    case
        when not exists (
            select
            t1.customer_number
            from orders_table as t1
            inner join (
                select
                customer_number
                from customers_table
                where ultimate_parent_number = @ultimate_parent_number
            ) as t2
            on t2.customer_number = t1.customer_number
            where t1.order_date between @existing_customer_begin_date
            and @existing_customer_end_date
        )
        then 1
        else 0
    end
)
return @return

end
go

1 个答案:

答案 0 :(得分:0)

使用cross apply尝试这样做,同时检查索引,告诉管理工作室带来实际的执行计划,你可能会找到索引的建议here is how

set ansi_nulls on
go
set quoted_identifier on
go

create function dbo.is_new_customer (
@ultimate_parent_number nvarchar(255),
@existing_customer_begin_date date,
@existing_customer_end_date date
)
returns int
as
begin
declare @return int

set @return = (
    case
        when not exists (
            select
            t1.customer_number
            from 
            (select
                customer_number
                from customers_table
                where ultimate_parent_number = @ultimate_parent_number) as t2

            cross apply ( select * from orders_table as t1 where t2.customer_number = t1.customer_number) as t1
            where t1.order_date between @existing_customer_begin_date
            and @existing_customer_end_date
        )
        then 1
        else 0
    end
)
return @return

end
go

这也可以帮助您了解如何加快查询速度 When should I use Cross Apply over Inner Join?