Как сравнить значения из двух отдельных запросов, но не использовать внутренний цикл?

Я работаю над своим проектом, где я должен сравнить значения из базы данных со значениями из файла.csv. я использовал 'cfhttp' чтобы преобразовать мой.csv в запрос, а затем я перебираю этот запрос и другой запрос, который использовал для получения значений из БД. Внутри этих двух циклов я использовал операторы 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#">

Также мне было интересно, можно ли с помощью тега cfhttp выйти только из тех столбцов, которые мне нужны из моего.csv? Теперь я собираю все столбцы из моего.csv, даже если я использую только два из них - столбцы A и W. Также возможно присоединение к запросу из 'cfhttp' на мой запрос из БД? Если кто-нибудь может дать мне совет по этому проекту, пожалуйста, дайте мне знать.

1 ответ

Поэтому я думаю, что вы заинтересованы только в данных, где records.A равно getRecords.UR_NUMBER, Вы можете использовать Query of Queries, чтобы получить пересечение двух наборов данных. Что-то вроде:

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

Это должно дать вам объединенный набор данных, который вы можете затем просмотреть и построить свои списки. Как отметил Мэтт Буш в комментариях, операции со списком выполняются медленно, поэтому arrayAppend будет быстрее.

Если Query или Query слишком медленный, вам может потребоваться преобразовать один из наборов записей в структуру (из пар ключ-значение), так как поиск выполняется быстрее. Например:

<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>
Другие вопросы по тегам