如何比较两个单独的quires的值但不使用内部循环?

时间:2016-05-24 15:30:30

标签: sql csv coldfusion cfquery cfhttp

我正在处理我的项目,我必须将DB中的值与.csv文件中的值进行比较。我已经使用'cfhttp'将我的.csv转换为查询,然后我遍历该查询和我用来从DB获取值的另一个查询。在这两个循环中,我使用if语句来比较我的值并检查它们是否匹配。然后我将它们存储在列表中,并在cfquery标签中使用这些列表进行更新。我在数据库中有14k记录,在我的.csv文件中有大约相同数量的记录。我的当前代码需要不到2分钟的时间将列表中的记录输出到屏幕以进行测试。我仍然没有测试更新需要多长时间。在我运行更新之前,我想看看你们中是否有人会为我的项目推荐任何其他方法?我可以将执行时间缩短到现在的水平吗?这是我的代码:

<cfhttp name="records" columns="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X" method="get" url="http://path to csv/temp.csv"/>

<cfquery name="getRecords" datasource="test">
    Select s.ID, f.URID, s.UR_NUMBER, CODE, f.FIELD
    From USERS s
    Left Outer Join MAPS f
    ON s.ID = f.URID
</cfquery>  

<cfset NumA = "">
<cfset NumB = "">
<cfset NumC = "">

<cfset NumD = "">
<cfset NumE = "">
<cfset updNumD = "">
<cfset updNumE = "">

<cfloop query="records">
    <cfloop query="getRecords">
        <cfif records.A EQ getRecords.UR_NUMBER>
            <cfif records.W NEQ getRecords.CODE>
                <cfif records.W EQ 'A'>
                    <cfset NumA = ListAppend(NumA,"#records.A#")>   
                <cfelseif records.W EQ 'B'>
                    <cfset NumB = ListAppend(NumB,"#records.A#")>
                <cfelse>
                    <cfset NumC = ListAppend(NumC,"#records.A#")>
                </cfif>
            </cfif>

            <cfif getRecords.URID EQ ''>
                <cfif records.W EQ 'D'>
                    <cfset NumD = ListAppend(NumD, "#getRecords.ID#")>
                <cfelseif records.W EQ 'E'>
                    <cfset NumE = ListAppend(NumE, "#getRecords.ID#")>
                </cfif>
            <cfelse>
                <cfif records.W EQ 'E'>
                    <cfset updNumD = ListAppend(updNumD, "#getRecords.URID#")>
                <cfelseif records.W EQ 'D'>
                    <cfset updNumE = ListAppend(updNumE, "#getRecords.URID#")>
                </cfif>
            </cfif> 
        </cfif>
    </cfloop>
</cfloop>

这里我将我的列表转储到屏幕上:

<cfdump var="#NumA#">
<cfdump var="#NumB#">
<cfdump var="#NumC#">
<br>
<cfdump var="#NumE#">
<cfdump var="#NumD#">
<br>
<cfdump var="#updNumE#">
<cfdump var="#updNumD#">

此外,我想知道是否可以从我的.csv中获取我需要的cfhttp标签?现在,即使我只使用其中两个列A和W,我也会从我的.csv中添加所有列。还可以将'cfhttp'中的查询连接到来自DB的查询吗?如果有人能就这个项目给我一些建议,请告诉我。

1 个答案:

答案 0 :(得分:2)

所以我认为您只对records.A等于getRecords.UR_NUMBER的数据感兴趣。您可以使用查询查询来获取两个数据集的交集。类似的东西:

<cfquery name="intersection" dbtype="query">
  select *
  from records, getRecords
  where records.A = getRecords.UR_NUMBER
</cfquery>

这应该为您提供组合数据集,然后您可以循环并构建列表。正如Matt Busche在评论中提到的,列表操作很慢,因此arrayAppend会更快。

如果查询或查询太慢,那么您可能希望将其中一个记录集转换为结构(键值对),因为查找速度更快。例如:

<cfscript>
// convert to structs as key lookups are fast
dbData = {};
for (row in getRecords) {
    dbData[row.UR_NUMBER] = row;
}

csvData = {};
for (row in records) {
    if (structKeyExists(dbData, row.A)) {
        // we have a match, so build the lists here...
        writeDump(dbData[row.A]);
    }
}
</cfscript>