0

背景/目的: 我正在创建一个包含 SQL 的冷融合文档,用于从我公司的数据库中获取值。我正在查找我们团队中每个销售代表的转化率(已售出的许可证/注册)。每个 Rep 都有一个RegionalDirectorID与用户绑定的 ID ( ) 以帮助跟踪。

问题/问题:问题是我们有其他工作人员在这里或那里销售许可证,例如我们的首席执行官、首席开发人员等。我们有 8 名销售代表,其中UserType8 名。我正在使用另一个查询来选择这些用户类型,以区分来自其他人,这样我们的数据也不会混淆选择它们。

正如您在下面看到的,我正在使用 cfloop 循环getUsers查询,特别是为了帮助该行(Users.RegionalDirectorID = #getUsers.UserID#)打印出我们销售代表的所有 ID。 当我没有输入 cfloop 时,我只会看到一行显示一位销售代表。如果我有 cfloop,我会得到最后一个销售代表。

代码:

<cfset myQuery = QueryNew("ID, ConversionRate")> 

<cfquery name="getUsers" datasource="#dsn#">
    Select UserID FROM USERS WHERE 
    UserTypeID = 8
    AND ISACTIVE = 1
</cfquery> 

<cfquery name="getREGRD" datasource="#dsn#">
 Select COUNT(DISTINCT(Users.UserID))  AS TOTALREG, RegionalDirectorID
 FROM Users
 WHERE UserTypeID = 3
<!---   <cfloop query="getUsers">
    AND (Users.RegionalDirectorID = #getUsers.UserID#)
    </cfloop>--->
AND (PARENTID IS NULL OR PARENTID = 0)
        <cfif len(selectMonth)>
            AND MONTH(Users.DateStamp) = #selectMonth#
        <cfelse>
            AND MONTH(Users.DateStamp) = #MONTH(NOW())#
        </cfif>
        GROUP BY Users.RegionalDirectorID
</cfquery> 

<cfquery name="getREGRDSold" datasource="#dsn#">
    Select COUNT(DISTINCT(UserTractLicense.UserID))  AS TOTALSOLD, Users.RegionalDirectorID
    FROM  Users, UserTractLicense 
    WHERE Users.UserID = UserTractLicense.UserID 
    AND   Users.UserTypeID = 3 AND
    (PARENTID IS NULL OR PARENTID = 0)
    <cfif len(selectMonth)>
            AND MONTH(Users.DateStamp) = #selectMonth#
    <cfelse>
            AND MONTH(Users.DateStamp) = #MONTH(NOW())#
    </cfif>
    GROUP BY Users.RegionalDirectorID
</cfquery> 

<!---<cfset newRow = QueryAddRow(myQuery, #getREGRD.RecordCount#)>
    <cfloop query="getREGRD">
        <cfset QuerySetCell(myQuery, "ID",  #getREGRD.RegionalDirectorID#, getREGRD.currentRow) />
    </cfloop>   
    <cfloop query="getREGRDSold">
        <cfset QuerySetCell(myQuery, "ConversionRate", #getREGRDSold.TOTALSOLD#/#getREGRD.TOTALREG#, getREGRDSold.currentRow) /> 
    </cfloop>
--->

<!---<cfdump var="#myQuery#">--->
<cfdump var="#getREGRD#">
<cfdump var="#getREGRDSold#">

<cfoutput query="getREGRDSold">
    #getREGRDSold.RegionalDirectorID#
</cfoutput>

cfloop 导致 newQuery 射出下面的错误。这就是为什么其中一些被注释掉的原因:

计算 QueryAddRow 函数时出错:QueryAddRow 函数的 Parameter> 2, 0 必须是正整数。
错误发生在第 70 行。

结果数据有一些没有 UserTypeID 为 8 的 RegionDirectorID,例如我想从查询结果中删除的 NULL 单元格。

样本结果

4

1 回答 1

0

听起来您只需要一个 JOIN,而不是所有额外的循环和查询。

如果该Users表同时存储客户和销售代表,您将需要一个self join。换句话说,Users使用aliases将表连接到自身。然后根据适当的用户类型过滤每一个。像这样的东西:

SELECT  cust.RegionalDirectorID
        , COUNT(DISTINCT(lic.UserID))  AS TOTALSOLD
FROM    Users cust
           INNER JOIN Users sales ON sales.UserID = cust.RegionalDirectorID
           INNER JOIN UserTractLicense lic ON lic.UserID = cust.UserID
<!--- customers --->
WHERE   cust.UserTypeID = 3 
<!--- sales reps --->
AND     sales.UserTypeID = 8
... etcetera 
GROUP BY cust.RegionalDirectorID

其他一些评论:

  1. 虽然在技术上并不总是需要,但当查询涉及多个表时,完全限定所有列名是一种很好的做法。

  2. 同样,请务必确定所有变量的范围。例如,使用FORM.selectMonthorURL.selectMonth而不是 just selectMonth

  3. 始终用于cfqueryparam所有可变查询参数。最重要的原因是保护您的数据库免受 sql 注入。它还有助于提高多次执行的查询的性能。

MONTH(Users.DateStamp) = #selectMonth#

  1. 我注意到查询只过滤月份数(不是月份年份)。因此,如果 selectedMonth = 8,查询将返回“八月”月份的结果 - 在任何一年。那是你的意图吗?如果没有,您显然还需要添加年份过滤器。但是,在索引列上使用函数通常会阻止数据库使用索引。因此,您可以考虑使用这种对索引更友好的范例

     WHERE  TheDateColumn >= TheStartDateAtMidnight         
     AND    TheDateColumn < TheDayAfterEndDateAtMidnight   
    
于 2016-08-12T16:26:16.253 回答