Как предотвратить несколько итераций одного и того же CFQuery в CFLoop и форматировать в матрицу

Я исследовал это совсем немного и не нашел ответа, который я ищу. Я смог добраться до этого момента с небольшой помощью, но теперь застрял на еще одном препятствии.

Я хотел бы иметь возможность отображать все УНИКАЛЬНЫЕ названия компаний в крайнем левом столбце, а затем «подсчет» количества тестов каждого типа, проведенных в течение определенного месяца. Я закомментировал часть своего кода, который, хотя и работает, не учитывает, когда номер конкретного теста равен нулю (нет записей в БД, соответствующих условиям), что необходимо, по крайней мере, для убедитесь, что другие тесты не перепутали свои «счета». Мой код, вероятно, поможет уточнить:

<cfset s = structNew()>
<cfquery datasource="test" name="qry">
    SELECT company, test_type, count(test_type) as counter 
    FROM donor_log
    GROUP BY company, test_type
</cfquery>

<cfloop query="qry">
    <cfset s[qry.company][qry.test_type] = qry.counter>
</cfloop>

<table border="1">
    <tr>
        <th>Company</th>
        <th>UA</th>
        <th>BA</th>
        <th>Hair</th>
        <th>Blood</th>
    </tr>
    <cfoutput>
    <cfloop collection="#s#" item="i">
        <tr>
            <td>#i#</td>
            <cfloop collection="#s[i]#" item="j">
                <cfquery dbtype="query" name="ua">
                    SELECT DISTINCT company 
                    FROM qry 
                    WHERE company='#i#' 
                      AND test_type='UA'
                </cfquery>
                <cfdump var="#ua#"> 
                <!---
                <cfif val(s[i][j]) EQ 0>
                    <td>0</td>
                <cfelse>  
                    <td>#s[i][j]#</td>
                </cfif>
                 --->
            </cfloop>  
        </tr>
    </cfloop> 
    </cfoutput>

Раздел с комментариями не выводит на экран «0», когда значение structKey равно 0, и в настоящее время, если у компании, скажем, 0 UA, но 2 BA, ячейка под UA показывает 2, а BA ничего не имеет. Значит, и с моим <cfif> утверждением что-то не так, но я не уверен, что именно. Пожалуйста, поймите, я только начинаю изучать ColdFusion, и большая часть того, что у меня есть на этой конкретной странице, взята из сообщения другой доброй души на другом форуме. Жду ваших ответов и отзывов, заранее спасибо!

Быстрое редактирование PS: когда я использую <cfdump>, как указано выше, на выходе получается 1 полный запрос для компании с 1 такой записью company="#i#" AND test_type="UA", 2 запроса для компании с 2 такими записями, 3 запроса для 3 совпадающих записей и так далее. В конечном итоге хотелось бы, чтобы этот запрос выполнялся только ОДИН РАЗ для каждой компании "#i#", а затем вытягивал s[i][j].recordcount (где бы он не был равен 0), чтобы затем я мог сравнить его с другой таблицей (графиком сборов) и сгенерировать общую сумму для выставления счета каждому. компания на основе количества проведенных тестов, если это имеет смысл, но сначала мне нужно пересечь этот мост.


person Brandon G    schedule 04.02.2013    source источник
comment
Это похоже на сводной отчет. Вы можете изучить использование sql pivot вместо создания этого в CF. ЕСЛИ ваша база данных поддерживает это. 1) Какой тип и версию БД вы используете? 2) Сколько существует типов тестов? Существует ли фиксированное количество типов? (Кстати, обязательно всегда указывайте тип и версию базы данных с вопросами запроса).   -  person Leigh    schedule 05.02.2013


Ответы (1)


Если я правильно понимаю ваш вопрос, я бы просто реорганизовал запрос, как показано ниже.

<cfquery datasource="test" name="qry">
SELECT company, SUM(CASE WHEN test_type = 'UA' THEN 1 ELSE 0 END) AS UACount
, SUM(CASE WHEN test_type = 'BA' THEN 1 ELSE 0 END) AS BACount
, SUM(CASE WHEN test_type = 'Hair' THEN 1 ELSE 0 END) AS HairCount
, SUM(CASE WHEN test_type = 'Blood' THEN 1 ELSE 0 END) AS BloodCount
FROM donor_log
GROUP BY company
</cfquery>

а затем вывод

<table border="1">
<tr>
    <th>Company</th>
    <th>UA</th>
    <th>BA</th>
    <th>Hair</th>
    <th>Blood</th>
</tr>
<cfoutput query="qry">
 <tr>
  <td>#qry.Company#</td>
  <td>#qry.UACount#</td>
  <td>#qry.BHCount#</td>
  <td>#qry.HairCount#</td>
  <td>#qry.BloodCount#</td>
 </tr>
</cfoutput>
person Matt Busche    schedule 04.02.2013
comment
Я думал что-то в том же духе. Я отредактировал ваш ответ, чтобы выходные переменные соответствовали именам, которые вы указали в запросе. - person Miguel-F; 05.02.2013
comment
+1. Да, я собирался предложить это дальше :) Но я не был уверен, что количество типов тестов фиксировано. Если да, то case будет работать очень хорошо, и в отличие от pivot синтаксис совместим с большинством баз данных. - person Leigh; 05.02.2013
comment
Судя по всему, мои правки ушли в битрейт. Думаю, мне не хватает репутации или что-то в этом роде??? :/ - person Miguel-F; 05.02.2013
comment
@ Miguel-F Я не могу одобрить ваши правки, поэтому я просто исправил это сам. - person Matt Busche; 05.02.2013
comment
Без проблем. Спасибо за обновление вашего ответа. - person Miguel-F; 05.02.2013
comment
Мэтт, спасибо, я действительно был в тупике, похоже, я слишком много думал :) Спасибо тебе! На самом деле я не знал, что вы можете сделать так много с SQL, а не с использованием CF, но я должен был упомянуть, что я также относительно новичок в SQL. @ Miguel-F Спасибо за вклад, несмотря ни на что, я ценю это! - person Brandon G; 05.02.2013
comment
Спасибо вам, Ли, и должным образом отметили re: движок БД, я вспомню об этом в следующем посте :) - person Brandon G; 05.02.2013
comment
@BrandonG, поскольку вы новичок в sql, я слышал хорошие отзывы о книге Teach Yourself SQL in 10 Minutes. Мигель-Ф, что бы ни случилось с вашими правками, это произошло не из-за отсутствия репутации. У вас оправданно выше, чем у меня, и я это сделал. - person Dan Bracuk; 05.02.2013
comment
Руди Лаймбак написал замечательную книгу по SQL под названием «Просто SQL». Очень легко читать и понимать. Не говоря уже о том, что он скрывается в сообществе CF, поэтому, если вы хотите подключить брата, проверьте это. - person Travis; 05.02.2013
comment
@DanBracuk - Это было из-за уровня репутации. Пока вы не наберете определенное количество баллов (не помню сколько), правки других ответов помещаются в очередь для просмотра, и трое из пяти членов должны проголосовать, чтобы одобрить или отклонить его. Рецензенты не обязательно являются специалистами по CF, просто тот, кто случайно делает обзор, проверяет его первым. - person Leigh; 05.02.2013