Sql 用相关值替换字符串公式的部分

Sql 用相关值替换字符串公式的部分,sql,ms-access,vba,Sql,Ms Access,Vba,我有一个表tbl_Composites,其中包含用于计算性能分数的公式。e、 g KPI | FORMULA | -------------------------------------------------- Productivity | [ItemsCompleted]/[LoggedInTime] | SalesConversion| [Sales]+[Leads]/[TotalCalls] |

我有一个表tbl_Composites,其中包含用于计算性能分数的公式。e、 g

     KPI       |           FORMULA                | 
--------------------------------------------------
Productivity   |  [ItemsCompleted]/[LoggedInTime] | 
SalesConversion|  [Sales]+[Leads]/[TotalCalls]    | 
还有另一个表tbl_BaseData,其中有一列包含这些指标和每个人的关联值

 SCOREDATE | USERID  |    METRIC       | VALUE | 
------------------------------------------------
01/03/2017 | 20511   | ItemsCompleted  |  50   | 
01/03/2017 | 20511   | LoggedInTime    |  320  | 
01/03/2017 | 20630   | Sales           |  8    | 
01/03/2017 | 20630   | Leads           |  3    | 
01/03/2017 | 20630   | TotalCalls      |  25   | 
我正在尝试编写一个VBA函数,该函数将获取日期、用户ID和KPI的参数,然后获取该KPI公式的相关度量值并计算结果

我有一些我已经设法整理好的东西,但它不是很有效,如果其中一个指标没有记录,它就不起作用,例如有人接了电话但没有销售

函数CalulateFormulastrFormula作为字符串,用户ID作为字符串,scoreDate作为日期作为字符串 Dim公制为字符串,valueList为字符串 作为整数的Dim i 对于透镜公式i=1 如果公式i,1=[那么 公制=公制公式,i+1,英制+1,标准公式,]-i-1 valueList=valueList&'&度量值&', 计算公式=计算公式和公制 i=仪器+1,标准公式,] 其他的 计算公式=计算公式和中间公式,i,1 如果结束 接下来我 valueList=LeftvalueList,LenvalueList-2 CalulateFormula=评估QLCALULATEFORMULA,值列表,用户ID,计分日期 端函数 这将构建公式字符串并填充需要查找的度量的列表。然后它调用另一个函数,如下所示,该函数运行一些SQL来获取度量值并计算公式

函数EvaluateSQLCalulateFormula为字符串,valueList为字符串,userID为字符串,scoreDate为日期为字符串 作为字符串的Dim strSQL Dim rs作为DAO.Recordset strSQL=选择度量、度量值和_ 来自tbl_BaseData&_ 其中,&valueList&和userID='&userID&'和scoreDate=&FormatscoreDate,mm/dd/yyyy& 设置rs=CurrentDb.OpenRecordsetstrSQL 直到R.EOF为止 CalulateFormula=替换CalulateFormula,rs!米制,卢比!度量值 下一个 环 EvaluateSQL=EvalCalulate公式 端函数
这似乎是一种非常迂回的做事方式,我想知道我是否需要从一个完全不同的角度来处理这个问题。有没有人能告诉我,是否有一种更简单/更有效的方法也能处理空值/缺失值?

看起来您在考虑字符串的生成。您的公式值已包含计算操作/,因此您可以读取公式的完整值作为SQL计算。看起来您非常关心公式值中的括号,但是SQL会将[ItemsCompleted]读取为计算的有效字段名

与上述方法相比,您可以完全在SQL代码中实现这一点

这里真正需要的是每天每个用户一行。有了它,您可以轻松运行您的度量;你甚至不需要tbl_组合表

下面是你如何做到的:

SELECT
    SCOREDATE
    ,USERID
    ,ItemsCompleted / LoggedInTime as Productivity
    ,Sales + Leads as SalesConversion
    from
    (SELECT distinct 
        base.SCOREDATE, 
        base.USERID, 
        ic.ItemsCompleted,
        lt.LoggedInTime,
        sls.Sales,
        lds.Leads,
        tc.TotalCalls
    from (((((
    tbl_BaseData as base
        left join
            (SELECT SCOREDATE, USERID, VALUE as ItemsCompleted
            from tbl_BaseData
            where METRIC = 'ItemsCompleted') as ic
            on base.USERID = ic.USERID
                and base.SCOREDATE = ic.SCOREDATE)
        left join
            (SELECT SCOREDATE, USERID, VALUE as LoggedInTime
            from tbl_BaseData
            where METRIC = 'LoggedInTime') as lt
            on base.USERID = lt.USERID
                and base.SCOREDATE = lt.SCOREDATE)
        left join
            (SELECT SCOREDATE, USERID, VALUE as Sales
            from tbl_BaseData
            where METRIC = 'Sales') as sls
            on base.USERID = sls.USERID
                and base.SCOREDATE = sls.SCOREDATE)
        left join
            (SELECT SCOREDATE, USERID, VALUE as Leads
            from tbl_BaseData
            where METRIC = 'Leads') as lds
            on base.USERID = lds.USERID
                and base.SCOREDATE = lds.SCOREDATE)
        left join
            (SELECT SCOREDATE, USERID, VALUE as TotalCalls
            from tbl_BaseData
            where METRIC = 'TotalCalls') as tc
            on base.USERID = tc.USERID
                and base.SCOREDATE = tc.SCOREDATE))
        as p
内部查询将数据合并为每个用户一行,并说明不存在的记录类型。它单独返回:

SCOREDATE用户ID项已完成的日志销售线索TotalCalls 2017年3月1日20511 50 320空 2017年3月1日20630空8 3 25 然后,外部查询计算生产率和SalesConversion。您可以为您需要的任何其他度量添加行。它返回:

SCOREDATE用户标识转换 2017年3月1日20511 0.156空 2017年3月1日20630零11
嗨,罗米努斯。谢谢你的回复。我不确定如何将公式直接输入到sql计算中,因为公式的部分不是字段,而是保存在[metric]字段中的值。你能举例说明你的意思吗?此外,我将公式的各个部分放在方括号中,这样我编写的函数就可以知道它们的开始和结束位置,但如果有更好的方法,我肯定会改变它。我看得越多,我越认为表结构是造成这种复杂性的根本原因。您提到如果没有特定类型的记录,您会遇到问题;您是否可以创建一个值为零的记录,而不是不创建记录?无论如何,这对记录保存来说更有意义,我想。好吧,完全用SQL重新定义,它可以处理不存在的记录。噢,我没想到会有这么全面的答案。非常感谢你花了这么多时间在这上面。不幸的是,我曾尝试运行此SQL查询,但收到一条错误消息,说查询表达式中缺少语法错误运算符。我试图理解它,看看是否可以找出它不喜欢的部分,但我不确定它为什么不工作。哈哈!只是Access需要将嵌套联接括起来。我已经编辑了你的答案,现在效果很好。非常感谢你,我有一个解决问题的方法,我也学到了很多 不是什么。我真的很感谢你的帮助!