【问题标题】:How to reduce an query of query for each month如何减少每个月的查询次数
【发布时间】:2018-07-31 13:20:48
【问题描述】:

我正在使用 My Sql 5.7 和 CF11。我想从下面的查询中获取每个月的总 qTotalPrice 和 quoteKeyID。但不是一整年。我想从当月到最近六个月的数据(从 7 月到 2 月)获取它。如果特定月份没有数据,我需要将特定月份显示为 0。

<cfquery name="thisYearsQuotes" datasource="myDB">
    SELECT * , MONTH(qDateTime) as qMonth
    FROM Quotes
    INNER JOIN Accounts
    ON Quotes.aID = Accounts.aID
    WHERE Accounts.aID = <cfqueryparam value="#VNAI.aID#" cfsqltype="cf_sql_clob" maxlength="255">
    AND Quotes.qDateTime > DATE_ADD(NOW(), INTERVAL -365 DAY)
</cfquery>

这些查询的结果

为了获取每个月的记录,我编写了如下查询。

获取当前月份

<cfquery name="SalesTotalThisMonth" dbtype="query">
    SELECT SUM(qTotalPrice) as DollarTotal , COUNT(quoteKeyID) as QuoteCount
    FROM thisYearsQuotes
    WHERE qMonth = #MONTH(NOW())#
</cfquery>

为了得到一个月的回报

<cfquery name="SalesTotal1MonthAgo" dbtype="query">
    SELECT SUM(qTotalPrice) as DollarTotal , COUNT(quoteKeyID) as QuoteCount
    FROM thisYearsQuotes
    WHERE qMonth = #MONTH(DateAdd("m",-1,NOW()))#
</cfquery>

为了获得两个月的回报,

<cfquery name="SalesTotal2MonthAgo" dbtype="query">
    SELECT SUM(qTotalPrice) as DollarTotal , COUNT(quoteKeyID) as QuoteCount
    FROM thisYearsQuotes
    WHERE qMonth = #MONTH(DateAdd("m",-2,NOW()))#
</cfquery>

等等...明智地我必须得到最后六个月。所以我每个月都写了一些查询。

有没有可能减少代码?

【问题讨论】:

  • 您是否尝试返回过去 12 个月的 单人 总数。前任。 750 美元 - 或者您想要过去 12 个月中每个的个人总计。前任。 2018 年 1 月 - 200 美元,2018 年 2 月 - 总计 175 美元,3 月 - 总计 375 美元,等等...
  • 顺便说一句,列数据类型可能不是cf_sql_clob,通常最好同时包含年份和月份以在时间段重叠的情况下进行区分(尽管不会有任何在这里...)。
  • @Ageax。是的。但不是一整年。我想从当月到最近六个月的数据(从 7 月到 2 月)获取它。如果没有特定月份的数据,我需要将特定月份显示为 0。
  • 好的,请看下面我的回答。

标签: mysql coldfusion cfml coldfusion-11


【解决方案1】:

更新

解决方案是为您需要的所有月份创建一个查询,然后使用左连接。

SELECT 8 AS monthNum UNION SELECT 7 AS m UNION SELECT 6 AS m UNION SELECT 5 AS m UNION SELECT 4 AS m UNION SELECT 3 AS m

所以为了使其自动化,我添加了一些 CF 代码来创建上述查询。

<cfset today=now()>
<cfset start = 0>
<cfset numberOfMonths = 6>
<cfset listOfMonths = ''>
<cfloop condition="numberOfMonths+start GT 0">
  <cfset listOfMonths = listappend(listOfMonths, ' SELECT ' & Month(DateAdd('m', start, today)) & ' AS m ')>
  <cfset start-->
</cfloop>
<cfoutput>
<cfquery>
  SELECT SUM(O.order_Total) AS totalOrder, COUNT(O.order_ID) AS numOrders, MONTH(O.order_Date) AS qMonth
  FROM tbl_orders O 
    RIGHT JOIN (
      #ListChangeDelims(listOfMonths, 'UNION')#
    ) monthList ON monthList.m = MONTH(O.order_Date) AND O.order_Date > DATE_ADD(NOW(), INTERVAL -6 MONTH)
  GROUP BY qMonth;
</cfquery>
<cfoutput>

首字母

我认为您可以使用正确的group by 在单个查询中完成。

<cfquery name="thisYearsQuotesPerMonth" datasource="mySQL_MILESTONEBMDB">
    SELECT 
      SUM(qTotalPrice) AS DollarTotal, COUNT(quoteKeyID) AS QuoteCount, MONTH(qDateTime) as qMonth
    FROM 
      Quotes
      INNER JOIN Accounts ON Quotes.aID = Accounts.aID
    WHERE 
      Accounts.aID = <cfqueryparam value="#VNAI.aID#" cfsqltype="cf_sql_clob" maxlength="255">
      AND Quotes.qDateTime > DATE_ADD(NOW(), INTERVAL -6 MONTH)
    GROUP BY qMonth
</cfquery>

【讨论】:

  • 返回值为一年的月份。我想从当前月份获得最后六个月。如果月份有数据,那么应该按照上面的查询计算总计。如果月份没有记录,那么应该在查询中显示为 0。
  • group by 将只返回 DB 中有记录的月份。但无论是否有记录,我都想返回过去六个月。希望你能理解我的情况。
  • 所以我把第一个子查询写成 WHERE qMonth = #MONTH(NOW())# 第二个子查询写成 WHERE qMonth = #MONTH(DateAdd("m",-2,NOW ()))# 第 3 个子查询为 WHERE qMonth = #MONTH(DateAdd("m",-3,NOW()))# etc.. 直到 WHERE qMonth = #MONTH(DateAdd("m",-5,现在()))#。所以我希望尽可能地改进我的查询。提前致谢。
  • @Kannan.P 我已经通过一些更改更新了我的答案。检查出。即使该月没有记录,查询也会为每个月返回一行。
  • 这行得通,但如果这用于多个查询,我再次推荐一个日历表。这是一次性设置,对于报告非常有用。我们在大多数数据库中都使用它们。 (开个玩笑 - RRK - RIGHT JOIN?哦,我的眼睛,我的眼睛!;-)
【解决方案2】:

我通过添加一个主表名称作为 reportmonths 得到了解决方案。其中有 12 行的数据,最后一年作为月和年列。因此,通过使用我的查询右连接该表来实现它。所以现在我可以使用 LIMIT 6 获得最近六个月的记录。

SELECT RP.ReportYear AS `year`, RP.ReportMonth AS `month`, A.DollarTotal, A.QuoteCount
    FROM
        (   
            SELECT
                YEAR(qDateTime) AS qYear, MONTH(qDateTime) AS qMonth,
                SUM(qTotalPrice) AS DollarTotal , COUNT(quoteKeyID) AS QuoteCount
            FROM Accounts A
                INNER JOIN Quotes Q ON A.aID = Q.aID
            WHERE A.aID = 216
            GROUP BY YEAR(qDateTime), MONTH(qDateTime)
        ) A
    RIGHT JOIN ReportMonths RP ON  RP.ReportYear = qYear 
    AND  RP.ReportMonth =  qMonth 
    ORDER BY `year` DESC, `month` DESC LIMIT 6

【讨论】:

  • 是的,这是日历表概念的一种变体。仅使用月份的一个问题是,如果某些时期没有数据,则结果的排序将关闭,因为 year 值将为空。例如,如果当前月份是 3 月,则订单可能不是 (10-Oct,11-Nov,12-Dec,01-Jan,02-Feb,03-Mar) 不确定这对您的情况是否重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多