0

AB ペアのデータベースをスキャンしている Coldfusion8/MySQL クエリに取り組んでいます。次に例を示します。

 S=2, M=2, L=2, XL=2

最初にこれを処理したスクリプトを改善しようとしていますが、これはエントリを 4 ペアに制限していました。なぜ最初に1 つの一致するペアを持つすべてのレコードを選択し、次にHAVINGを使用してすべてのペアが一致するレコードのみを選択するのか疑問に思っているからです。 .

これが元のクエリで、その後の私の現在のバージョンは次のとおりです。

<!--- placeholders --->
<cfparam name="s01" default="">
<cfparam name="s02" default="">
<cfparam name="s03" default="">
<cfparam name="s04" default="">
<cfparam name="q01" default="">
<cfparam name="q02" default="">
<cfparam name="q03" default="">
<cfparam name="q04" default="">
<!--- check length of user inputs --->
<cfset sizes = ListLen(s_lot_groesse,",")>
<cfset qtys   = ListLen(s_lot_menge,",")>
<!--- populate placeholders --->
<cfif sizes gt 0><cfset s01 = trim(ListGetAt(s_lot_groesse, 1,","))></cfif>
<cfif sizes gt 1><cfset s02 = trim(ListGetAt(s_lot_groesse, 2,","))></cfif>
<cfif sizes gt 2><cfset s03 = trim(ListGetAt(s_lot_groesse, 3,","))></cfif>
<cfif sizes gt 3><cfset s4 = trim(ListGetAt(s_lot_groesse, 4,","))></cfif>
<cfif qtys gt 0><cfset q01 = trim(ListGetAt(s_lot_menge, 1,","))></cfif>
<cfif qtys gt 1><cfset q02 = trim(ListGetAt(s_lot_menge, 2,","))></cfif>
<cfif qtys gt 2><cfset q03 = trim(ListGetAt(s_lot_menge, 3,","))></cfif>
<cfif qtys gt 3><cfset q04 = trim(ListGetAt(s_lot_menge, 4,","))></cfif>
<!--- query --->
<cfquery datasource="db" name="lotsuche">
SELECT styleno, count(*) as total_styles
FROM styles
WHERE 1 = 1
AND (
    <cfif s01 neq "" AND q01 neq "">(groesse = "#s01#" AND bestand >= "#q01#")</cfif>
    <cfif s02 neq "" AND q02 neq "">OR (groesse = "#s02#" AND bestand >= "#q02#")</cfif>
    <cfif s03 neq "" AND q03 neq "">OR (groesse = "#s03#" AND bestand >= "#q03#")</cfif>
    <cfif s04 neq "" AND q04 neq "">OR (groesse = "#s04#" AND bestand >= "#q04#")</cfif>
    )
GROUP BY styleno
HAVING total_styles= "#sizes#"
</cfquery>

新しいバージョン:

<!--- build a 2D array --->
<cfscript>
    variables.lotArray = ArrayNew(2);
    variables.sizeCounter = 1;
    variables.qtyCounter = 1;
</cfscript>
<cfloop list="#LOCAL.Search.s_lot_groesse#" delimiters=", " item="size">
    <cfscript>
        variables.lotArray[variables.lotCounter][1] = size;
        variables.lotCounter = variables.lotCounter + 1;
    </cfscript>
</cfloop>
<cfloop list="#LOCAL.Search.s_lot_menge#" delimiters=", " item="qty">
    <cfscript>
        variables.lotArray[variables.qtyCounter][2] = qty;
        variables.qtyCounter = variables.qtyCounter + 1;
    </cfscript>
</cfloop>
<!--- get array length --->
<cfset variables.lotArrayLen = arrayLen(variables.lotArray)>

<!--- query --->
<cfquery datasource="ds" name="lotsuche">
SELECT art.styleNo, count(*) as total_styles
FROM styles AS art
WHERE 1 = 1
<cfloop from="1" to="#variables.lotArrayLen#" index="i">
    AND ( art.groesse = <cfqueryparam cfsqltype="cfsql_varchar" value="#variables.lotArray[i][1]#"> 
    AND art.bestand >= <cfqueryparam cfsqltype="cfsql_varchar" value="#variables.lotArray[i][2]#">
</cfloop>
GROUP BY art.styleno
<!--- HAVING anzahl = "#variables.lotArrayLen#" --->
</cfquery>

質問: ORHAVINGが元のクエリで使用されている
理由がわかりません。これは、すべてのペアが一致するレコードを選択するのではなく、 1 つの一致するペアを持つすべてのレコードを選択しないためですか? スキャンするエントリが数百万ある場合、どちらのアプローチが優れていますか? また、私のように全体をリファクタリングすることは理にかなっていますか?

手伝ってくれてありがとう!

4

1 に答える 1

1

HAVING 句は集計関数で使用され、OR はクエリ内の複数の条件をテストするために使用されます。古いクエリの having 句の目的がわかりません。新しいクエリを徹底的にテストして、期待どおりの結果が得られることを確認しましたか?

2 つのクエリを調べた後、2 番目のクエリは同じようには機能しません。2 つのレコードには、満たす必要がある複数の条件が含まれている可能性があり、クエリは空のレコードセットを返す可能性があります。

このようなものをもっと探していると思います。

AND
 <cfloop from="1" to="#variables.lotArrayLen#" index="i">
 (  OR (art.groesse = <cfqueryparam cfsqltype="cfsql_varchar" value="#variables.lotArray[i][1]#"> 
AND art.bestand >= <cfqueryparam cfsqltype="cfsql_varchar" value="#variables.lotArray[i][2]#"> ) )

于 2012-05-21T18:06:16.027 に答える