Как объединить результаты запроса? - PullRequest
1 голос
/ 21 марта 2019

У меня есть три запроса, которые связаны между собой.Окончательный вывод требует нескольких циклов по запросам.Этот способ работает просто отлично, но, на мой взгляд, кажется неэффективным и слишком сложным.Вот что у меня есть:

Запрос 1:

<cfquery name="qryTypes" datasource="#application.datasource#">
   SELECT 
      t.type_id, 
      t.category_id,
      c.category_name, 
      s.type_shortcode
   FROM type t
      INNER JOIN section s 
         ON s.type_id = t.type_id
      INNER JOIN category c 
         ON c.category_id = t.category_id
   WHERE t.rec_id = 45 -- This parameter is passed from form field.
   ORDER BY s.type_name,c.category_name
</cfquery>

Типы запросов приведут к набору результатов:

4   11  SP  PRES
4   12  CH  PRES
4   13  MS  PRES
4   14  XN  PRES

Затем выполните цикл по типам запросов и получитезаписи из другого запроса для каждой соответствующей записи:

Запрос 2:

<cfloop query="qryTypes">
   <cfquery name="qryLocation" datasource=#application.datasource#>
      SELECT l.location_id, l.spent_amount
      FROM locations l
      WHERE l.location_type = '#trim(category_name)#' 
         AND l.nofa_id = 45 -- This is form field    
         AND l.location_id = '#trim(category_id)##trim(type_id)#'
      GROUP BY l.location_id,l.spent_amount
      ORDER BY l.location_id ASC
   </cfquery>

   <cfset spent_total = arraySum(qryLocation['spent_amount']) />
   <cfset amount_total = 0 />

   <cfloop query="qryLocation">           
      <cfquery name="qryFunds" datasource=#application.datasource#>
         SELECT sum(budget) AS budget
         FROM funds f
         WHERE f.location_id= '#qryLocation.location_id#' 
            AND nofa_id = 45
      </cfquery>

      <cfscript>
         if(qryFunds.budgetgt 0) {
            amount_total = amount_total + qryFunds.budget;
         }
      </cfscript>
   </cfloop>

   <cfset GrandTotal = GrandTotal + spent_total />
   <cfset GrandTotalad = GrandTotalad + amount_total />
</cfloop>

После завершения циклов это результат:

CATEGORY NAME   SPENT TOTAL   AMOUNT TOTAL
      SP           970927         89613
      CH           4804           8759
      MS           9922           21436
      XN           39398          4602
   Grand Total:    1025051        124410

Есть ли хорошийспособ объединить это и иметь только один запрос вместо трех запросов и внутренних циклов?Мне было интересно, если это подходит для хранимой процедуры, а затем все ли манипуляции с данными там?Если у кого-то есть предложения, пожалуйста, дайте мне знать.

1 Ответ

4 голосов
/ 21 марта 2019
  • qryTypes возвращает X записей
  • qryLocation возвращает Y записей

Итак, вы выполнили (1 + X) запросов.

  • qryFunds возвращает Z записей

Теперь вы выполнили (1 + X) (Y) запросов.

Чем больше данных будет возвращено, тем больше запросов вы будете выполнять.Очевидно, что это нехорошо.

Если все, что вам нужно, это итоговые итоги для каждой категории, в хранимой процедуре вы можете создать временную таблицу с объединенными данными из qryTypes и qryLocation.Затем ваш последний qryFunds просто объединяется с данными этой временной таблицы.

SELECT 
    sum(budget) AS budget
FROM 
    funds f
INNER JOIN 
    #TEMP_TABLE t ON t.location_id = f.location_id
AND 
    nofa_id = 45

Затем вы можете получить другие суммы с временной таблицы, если это необходимо.Вполне возможно, что все это можно объединить в один запрос, но, возможно, это поможет вам туда добраться.

Кроме того, хранимая процедура может возвращать несколько наборов записей, так что вы можете иметь один возврат агрегированных данных о количестве таблиц и2-й возврат итогов.Это сохранит все вычисления в базе данных и не потребует участия CF.

...