背景/目的:我正在创建一个包含SQL的coldfusion文档,用于从我公司的数据库中获取值。我在团队中找到了每位销售代表的转换率(销售/注册许可证)。每个代表都有一个ID(RegionalDirectorID
)与用户绑定,以帮助跟踪。
问题/问题:问题是我们有其他工作人员在这里或那里出售许可证,例如我们的首席执行官,首席开发人员等。我们有8名销售代表与UserType
我正在使用另一个查询来选择那些UserTypes,以区别于其他人,这样我们的数据也不会混淆选择它们。
如下所示,我使用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函数时发生错误:参数&gt; QueryAddRow函数的2,0,必须是正整数。
的 第70行发生错误。
结果数据有一些RegionDirectorID没有UserTypeID为8,例如NULL单元格,我想从查询结果中删除。
答案 0 :(得分:0)
听起来你只需要一个JOIN,而不是所有额外的循环和查询。
如果Users
表存储两个客户和销售代表,则需要self join。换句话说,使用aliases将Users
表连接到自身。然后在适当的用户类型上过滤每一个。像这样:
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
其他一些评论:
虽然技术上并不总是需要,但只要查询涉及多个表,就可以完全限定所有列名称。
同样,请务必确定所有变量的范围。例如,使用FORM.selectMonth
或URL.selectMonth
而不只是selectMonth
。
始终对所有变量查询参数使用cfqueryparam
。最重要的原因是保护您的数据库免受SQL注入。它还有助于提高多次执行查询的性能。
MONTH(Users.DateStamp) = #selectMonth#
我注意到查询只过滤了月份号(而不是月份和年份)。因此,如果selectedMonth = 8,则查询将返回“August”月份的结果 - 在任何年份。那是你的意图吗?如果没有,你显然也想要添加一年过滤器。但是,在索引列上使用函数通常会阻止数据库使用索引。因此,您可以考虑使用this paradigm which is more index friendly:
WHERE TheDateColumn >= TheStartDateAtMidnight
AND TheDateColumn < TheDayAfterEndDateAtMidnight