Coldfusion 循环查询并仅显示 html 标记一次

Coldfusion looping over query and display html tag only one time

我在循环 sql 查询时遇到问题,如果查询不为空,那么我必须显示一些 html 标记。问题是假设查询找到 3 个项目,它将显示 3x 文件而不是 1x。

这是我的代码:

<cfquery name="client_id" datasource="#application.dsn#">
    Select borrower_id,client_id,id from contracts where borrower_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(url.ID)#">
</cfquery>

<cfloop query="client_id">
    <cfquery name="Payment_log" datasource="#application.dsn#">
        SELECT *
        FROM paymentLog
        WHERE contract_id = <cfqueryparam value="#client_id.id#" maxlength="36" cfsqltype="CF_SQL_BIGINT">
            AND DateDelete IS NULL
        ORDER BY date_log, id
    </cfquery>

    <cfloop query="Payment_log">

        <cfquery name="payment_log_file" datasource="#application.dsn#">
            SELECT file_name
            FROM paymentLog_file
            WHERE log_id = #Payment_log.id#
        </cfquery>

        <cfloop query="payment_log_file">

            <cfif payment_log_file.recordCount neq 0>
                <th>file name</th>
            </cfif>
        </cfloop>
    </cfloop>
</cfloop>

这是结果

<th>file name</th>
<th>file name</th>
<th>file name</th>

这就是我want/need

<th>file name</th>

好的,所以我按照 Matt Busche 和 Dan Bracuk 的建议将 sql 查询更改为:

SELECT plf.log_id
FROM paymentLog pl
        LEFT JOIN paymentLog_file plf ON pl.id = plf.log_id
WHERE contract_id = <cfqueryparam value="#client_id.id#" maxlength="36" cfsqltype="CF_SQL_BIGINT">
        AND DateDelete IS NULL
ORDER BY plf.log_id, date_log, id

我明白了:

这就是我得到的

这就是我want/need

如果您只想 return 1 个文件,请在查询中说明。

<cfquery name="payment_log_file" datasource="#application.dsn#">
    SELECT TOP 1 file_name
    FROM paymentLog_file
    WHERE log_id = #Payment_log.id#
</cfquery>

如果您想在 HTML 标签内显示多个文件,只需将循环包裹在其中即可。

这是一条很长的评论。将其发布为答案使我能够使其具有可读性。

首先,运行 在另一个查询的循环中查询很少是个好主意。您问题中的代码表明您的 SQL 知识需要发挥作用。为什么不是从两个表中选择的单个查询?如果您不知道该怎么做,我听说过关于这本书的好消息,自学 SQL 在 10 分钟内。

其次,你说你只想显示三个记录中的一个。哪一个?如果您不知道,请询问希望完成此操作的人。这属于在开始编写代码之前了解代码应该完成什么的一般类别。

你会想比我做的更进一步,如果可能的话,将其减少到一个整体查询,但这应该会让你走上正轨

将您的两个内部查询合并为一个查询,在重复的行类型上添加一个 order by 属性,然后将一个 group by 属性添加到您的 cfloop。如果你在 CF10 上?或更低,您可能需要使用 cfoutput 而不是 cfloop 来使用 group 属性

<cfquery name="client_id" datasource="#application.dsn#">
 Select borrower_id,client_id,id from contracts where borrower_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(url.ID)#">
</cfquery>

<cfloop query="client_id">
  <cfquery name="Payment_log" datasource="#application.dsn#">
    SELECT pl.log_id log_id
    FROM paymentLog pl
        INNER JOIN paymentLog_file plf ON pl.log_id = plf.log_id
    WHERE contract_id = <cfqueryparam value="#client_id.id#" maxlength="36" cfsqltype="CF_SQL_BIGINT">
        AND DateDelete IS NULL
    ORDER BY pl.log_id, date_log, id
 </cfquery>

  <cfloop query="Payment_log" group="log_id">
    <th>file name</th>
  </cfloop>
</cfloop>

我建议将整个查询合并到一个数据集中,然后使用它来构建输出。

SELECT c.borrower_id,c.client_id,c.id AS contracts_id
    , pl.* /* But don't use *. Explicitly call only column names that you need. */
    , plf.[file_name] /* Brackets because "file_name" is a built-in SQL function. */
FROM  contracts c 
        LEFT OUTER JOIN paymentLog pl ON c.id = pl.contract_id   
            AND pl.DateDelete IS NULL
        LEFT OUTER JOIN paymentLog_file plf ON plf.log_id = pl.id
WHERE c.borrower_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#trim(url.ID)#">
ORDER BY pl.log_id, pl.date_log, pl.id /* Is this last ORDER BY needed? Which id are you wanting to sort on? Make sure it's in the SELECT. */

这还可以让您批量转储整个数据集,以便您可以看到您实际使用的是什么。从这里你应该能够得到它来输出你正在寻找的东西。

我也会在你将它传递给你的 cfqueryparam 之前验证你的 url.ID。