T-sql:当因素的数量可能随时不同时,计算因素的总和

T-sql:当因素的数量可能随时不同时,计算因素的总和,sql,tsql,logic,sql-server-2017,Sql,Tsql,Logic,Sql Server 2017,请你帮我开发计算客户评级的算法好吗。 初始数据集和期望的结果在下面的代码中。多谢各位 逻辑是: 我们有值为1或0的客户和6个因子存在或不存在 我们应计算客户的评级: 1最大速率-客户端具有所有因素 2-客户有因子1-5,没有因子6 3-客户有因素1-4,没有第5个因素6不重要 4-客户有因素1-3,没有第4个因素5-6无所谓 5-客户有因素1-2,没有第3个因素4-6无所谓 6-客户有因素1,没有第二因素3-6无所谓 7-客户没有因素1因素2-6无所谓 关键是,各种因素的数量有时会有所不同 dr

请你帮我开发计算客户评级的算法好吗。 初始数据集和期望的结果在下面的代码中。多谢各位

逻辑是: 我们有值为1或0的客户和6个因子存在或不存在

我们应计算客户的评级:

1最大速率-客户端具有所有因素

2-客户有因子1-5,没有因子6

3-客户有因素1-4,没有第5个因素6不重要

4-客户有因素1-3,没有第4个因素5-6无所谓

5-客户有因素1-2,没有第3个因素4-6无所谓

6-客户有因素1,没有第二因素3-6无所谓

7-客户没有因素1因素2-6无所谓

关键是,各种因素的数量有时会有所不同

drop table if exists #tmp;

create TABLE #tmp (
[client] [nvarchar] null,
    [factor1] [int] NULL,
    [factor2] [int] NULL,
    [factor3] [int] NULL,
    [factor4] [int] NULL,
    [factor5] [int] NULL,
    [factor6] [int] null,
    [desirable_result] [int] NULL
) 

insert into #tmp (
[client]
    ,[factor1]
    ,[factor2]
    ,[factor3]
    ,[factor4]
    ,[factor5]
    ,[factor6]
    ,[desirable_result]
)
select '1', 1,1,1,1,1,1,1 union all
select '2', 1,1,0,1,1,1,5 union all
select '3', 1,0,1,1,0,1,6 union all
select '4', 1,1,1,1,1,0,2 union all
select '5', 1,1,1,0,0,1,4
select *
, "factor1" + "factor2" + "factor3" + "factor4" + "factor5" + "factor6" sum_6
, "factor1" + "factor2" + "factor3" + "factor4" + "factor5" sum_5
, "factor1" + "factor2" + "factor3" + "factor4" sum_4
, "factor1" + "factor2" + "factor3" sum_3
, "factor1" + "factor2" sum_2
, "factor1" sum_1
into #tmp2
from #tmp

select * 
, case when sum_6 = 6 then 1 else 
(case when sum_5 = 5 and sum_6 < 6 then 2 else 
(case when sum_4 = 4 and sum_5 < 5 then 3 else 
(case when sum_3 = 3 and sum_4 < 4 then 4 else 
(case when sum_2 = 2 and sum_3 < 3 then 5 else 
(case when sum_1 = 1 and sum_2 < 2 then 6 else 
7
end)
end) 
end) 
end) 
end) 
end rate
from
#tmp2
此解决方案有效,但前提是因子数始终相等。 关键是,各种因素的数量有时会有所不同

drop table if exists #tmp;

create TABLE #tmp (
[client] [nvarchar] null,
    [factor1] [int] NULL,
    [factor2] [int] NULL,
    [factor3] [int] NULL,
    [factor4] [int] NULL,
    [factor5] [int] NULL,
    [factor6] [int] null,
    [desirable_result] [int] NULL
) 

insert into #tmp (
[client]
    ,[factor1]
    ,[factor2]
    ,[factor3]
    ,[factor4]
    ,[factor5]
    ,[factor6]
    ,[desirable_result]
)
select '1', 1,1,1,1,1,1,1 union all
select '2', 1,1,0,1,1,1,5 union all
select '3', 1,0,1,1,0,1,6 union all
select '4', 1,1,1,1,1,0,2 union all
select '5', 1,1,1,0,0,1,4
select *
, "factor1" + "factor2" + "factor3" + "factor4" + "factor5" + "factor6" sum_6
, "factor1" + "factor2" + "factor3" + "factor4" + "factor5" sum_5
, "factor1" + "factor2" + "factor3" + "factor4" sum_4
, "factor1" + "factor2" + "factor3" sum_3
, "factor1" + "factor2" sum_2
, "factor1" sum_1
into #tmp2
from #tmp

select * 
, case when sum_6 = 6 then 1 else 
(case when sum_5 = 5 and sum_6 < 6 then 2 else 
(case when sum_4 = 4 and sum_5 < 5 then 3 else 
(case when sum_3 = 3 and sum_4 < 4 then 4 else 
(case when sum_2 = 2 and sum_3 < 3 then 5 else 
(case when sum_1 = 1 and sum_2 < 2 then 6 else 
7
end)
end) 
end) 
end) 
end) 
end rate
from
#tmp2

您可以在需要时尝试使用CASE

select case 
    when  [factor1] = 1 
        AND [factor2] = 1 
        AND [factor3] = 1 
        AND [factor4] = 1
        AND [factor5] = 1 
        AND [factor6] = 1
    then 'ALL6'
    when  [factor1] = 1 
        AND [factor2] = 1 
        AND [factor3] = 1 
        AND [factor4] = 1
        AND [factor5] = 1 
    then 'FIRST5'
     .....
     ....
    when  [factor1] = 1 
        AND [factor2] = 1 
        AND [factor3] = 1 
        AND [factor4] = 1
    then 'FIRST4'


    when  [factor1] = 1 
    then 'ONLy1'     END client_rate 
from my_table 
chenge这个点。。。。在缺少条件的情况下,您可以在以下情况下使用CASE。。。正如斯凯里奇所证明的那样

这里我要做的是使用交叉应用取消对表的填充,然后使用带CASE的SUM来计算必要的逻辑

select  t.client, 
        t.[desirable_result],
        case    when    sum(f.fval) = 6 then 1
                when    sum(f.fval) = 5 
                and     sum(case when f.fno  = 6 then f.fval end) = 0 then 2
                when    sum(case when f.fno <= 4 then f.fval end) = 4 
                and     sum(case when f.fno  = 5 then f.fval end) = 0 then 3
                when    sum(case when f.fno <= 3 then f.fval end) = 3 
                and     sum(case when f.fno  = 4 then f.fval end) = 0 then 4
                when    sum(case when f.fno <= 2 then f.fval end) = 2 
                and     sum(case when f.fno  = 3 then f.fval end) = 0 then 5
                when    sum(case when f.fno  = 1 then f.fval end) = 1 
                and     sum(case when f.fno  = 2 then f.fval end) = 0 then 6
                when    sum(case when f.fno  = 1 then f.fval end) = 0 then 7
                end
from    #tmp t
        cross apply
        (
            values  
            (1, factor1),
            (2, factor2),
            (3, factor3),
            (4, factor4),
            (5, factor5),
            (6, factor6)
        ) f (fno, fval)
group by t.client, t.[desirable_result]
order by t.client

您使用的是MySQL还是SQL Server?Squirrel,我使用的是SQL Server 2017您想要的东西可以使用CASE来完成。这会有点难看,但它会起作用。为什么客户端5的结果为3,而只有因子1到3和1奇怪,感谢您的更正和理解的逻辑。客户端5的结果应为4。我会在一分钟内更正我的帖子。谢谢你的解决方案。如果因子的数量总是相等的话,效果会很好。我已经开发了您的解决方案,并将其发布在主题中。但当因素的数量时不时不同时,id就不起作用了。如果有动态SQL,那就太好了。@AlexIvanov。1这回答了您提出的问题,另一个回答也是如此。你应该接受答案。2个SQL表有固定数量的列,表或问题都没有动态性。3如果因子数量不同,则应修复数据模型,使因子以行而不是列的形式存储。4如果你有一个关于动态列数的问题,这是一个不同的问题,应该作为一个新问题来问。Squirrel,你的代码工作得很好,我会很乐意使用它。唯一剩下的就是:让它充满活力。输入值的格式始终相同:客户端和一些名为factor1、factor2、factorN的因子可能是5,也可能是25个因子。如果您可以规范化tmp表,将更容易。这就是交叉申请所做的。它解开并正常化它的怪癖,谢谢。我将花一些时间学习“交叉应用”功能,因为我没有太多的使用经验。