Mysql 用于查询季度支出数据的改进表结构

Mysql 用于查询季度支出数据的改进表结构,mysql,database-design,Mysql,Database Design,我正在为我公司的一个项目寻找关于最有效的表结构/SQL代码的建议。我不是一个专业的开发人员,所以一个更简单的解决方案是最好的 项目要求: 我想创建一个HTML表,按供应商类别按财政季度显示总支出,其中每个类别都是一个链接,可以单击该链接展开以获取供应商级别x业务部门级别的支出 我已经准备好了。我内置了PHP和MySQL。但是,在某些情况下,我运行以扩展表的查询运行得非常慢。我想彻底检查我的表结构和查询,使整个过程更加高效和灵活 我拥有的数据摘要 我每个季度从每个业务部门获取原始数据,并按供应商列

我正在为我公司的一个项目寻找关于最有效的表结构/SQL代码的建议。我不是一个专业的开发人员,所以一个更简单的解决方案是最好的

项目要求:

我想创建一个HTML表,按供应商类别按财政季度显示总支出,其中每个类别都是一个链接,可以单击该链接展开以获取供应商级别x业务部门级别的支出

我已经准备好了。我内置了PHP和MySQL。但是,在某些情况下,我运行以扩展表的查询运行得非常慢。我想彻底检查我的表结构和查询,使整个过程更加高效和灵活

我拥有的数据摘要

我每个季度从每个业务部门获取原始数据,并按供应商列出支出。我还有一个解码环,将供应商名称与供应商类别相匹配,例如星巴克->餐厅

我当前的流程 我将季度数据汇总到一个名为spendfile的表中,该表包含以下列:

卖方名称 标准供应商名称更正供应商名称中的拼写错误等。 供应商类别 一刻钟 花费 当我第一次收到一个用户的请求,要查看带有类别的HTML表,并按季度在单独的列中花费时,我创建了一个名为treetable的临时表,其中包含以下列:

rowlabel显示在表下方的类别/供应商名称 每个季度与供应商的支出单独列一列 支出Q2 支出3 支出Q4 花费 请注意,为了获得此表,我需要选择所有唯一的供应商类别,然后对每个季度的支出进行季度合计,最后将每个季度的季度总支出加入类别列表,因此我将进行5-6次合并,每个时间段1次

然后,我以非常简单的方式呈现为html表

当用户单击某个类别以获取更多详细信息时,我会经历一个类似的过程:获取唯一的供应商列表,汇总特定类别中所有供应商的时间,并将所有时间段作为单独的列合并

最后一步是将新的深入数据合并到所有供应商所属类别下右侧的树表中

有没有人对更好的方法有什么想法?我想做的有意义吗


谢谢

在不了解更多架构的情况下,很难提供具体的建议(如可能使用的SQL)。不过,我还是会努力的。这里有一些一般性的建议

试着慢慢地量化,这样你就可以知道你在改进时是否在改进。还要量化您处理的数据量。 只有在您绝对确定需要临时表时才使用它们。DBMS中最昂贵的===缓慢的事情之一是将数据写入表。如果不需要临时表,就不要使用它们。 如果可能的话,可以创建一个SQL查询,为希望从原始数据以HTML格式显示的表生成正确的列和行。然后,在命令行mySQL客户端中运行该查询,并使用EXPLAIN命令让mySQL告诉您它试图做什么。请看这里: 这里有一些关于该查询如何工作的更具体的建议。假设您的输入表具有此模式

vendorname
standard_vendor_name (corrects misspells in vendor name, etc.)
vendor_category (character string)
quarter (integer)
spend  (floating point)
假设您想要一个包含这些列的表

vendor_category
vendor (standardized spelling)
spend_q1
spend_q2
spend_q3
spend_q4
很抱歉,我不理解您关于如何处理输出中的供应商名称和类别的问题。我假设您只是简单地显示类别,然后显示每个供应商的名称,并按类别进行订购

我也不明白你是如何将季度存储在输入表中的。假设您在2011年第1季度至2012年第2季度使用的是数字格式,如201112011220113201142012120122

假设您想在html表中显示任意四个连续的四分之一,只是为了微笑

那么,我们开始吧

我们需要一个小的子查询来生成所需的四个季度ID,该ID基于您要显示的最近一个季度的ID,您需要提供该ID

SELECT DISTINCT QUARTER
  FROM INFO
 WHERE QUARTER <= ~~~the most recent quarter~~~
 ORDER BY QUARTER DESC
 LIMIT 0,4
不要加入这个,否则你会得到你所有的分类/供应商物品,包括你最近四个季度没有花钱的物品

现在我们需要把这一切放在一起。事情变得荒谬冗长,SQL不是很有趣吗?。我们必须把所有这些积木连接在一起。下面是我们的大查询的概要,以及显示构建块去向的注释

SELECT A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME, Q.SPEND, R.SPEND, S.SPEND, T.SPEND
  FROM (
     /* category combinations */
  )A
  LEFT JOIN (
     /* most recent quarter spend */
  )Q ON (           A.VENDOR_CATEGORY=Q.VENDOR_CATEGORY 
                AND A.STANDARD_VENDOR_NAME=Q.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* second most recent quarter spend */
  )R ON (           A.VENDOR_CATEGORY=R.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=R.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* third most recent quarter spend */
  )S ON (           A.VENDOR_CATEGORY=S.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=S.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* fourth most recent quarter spend */
  )T ON (           A.VENDOR_CATEGORY=T.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=T.STANDARD_VENDOR_NAME)
ORDER BY A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME
我将让您将子查询插入到这个大纲中

您可能已经使用了类似的方法来生成临时表。但是如果你做对了,你可以简单地使用这个大查询来生成你的报告。除非您的info表有数以百万计的行,否则如果您正确地为表编制索引,它将运行得相当快

如果你有无数行,你可能会为bi工作
g公司,该公司可以为一个更大的mySQL服务器提供快速磁盘和数GB的RAM。这也会加快速度,尤其是在您编制索引后。

我很乐意帮助您,但我需要更多信息。您能把您实际用来获取信息的查询放在一起吗?+1表示一个好问题,表示您的供应商拼写更正,表示解码器铃声
SELECT DISTINCT I.VENDOR_CATEGORY, I.STANDARD_VENDOR_NAME
  FROM INFO I
  JOIN (        
    SELECT DISTINCT QUARTER
      FROM INFO
     WHERE QUARTER <= ~~~the most recent quarter~~~
     ORDER BY QUARTER DESC
     LIMIT 0,4
 ) Q ON I.QUARTER=Q.QUARTER 
SELECT A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME, Q.SPEND, R.SPEND, S.SPEND, T.SPEND
  FROM (
     /* category combinations */
  )A
  LEFT JOIN (
     /* most recent quarter spend */
  )Q ON (           A.VENDOR_CATEGORY=Q.VENDOR_CATEGORY 
                AND A.STANDARD_VENDOR_NAME=Q.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* second most recent quarter spend */
  )R ON (           A.VENDOR_CATEGORY=R.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=R.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* third most recent quarter spend */
  )S ON (           A.VENDOR_CATEGORY=S.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=S.STANDARD_VENDOR_NAME)
  LEFT JOIN (
     /* fourth most recent quarter spend */
  )T ON (           A.VENDOR_CATEGORY=T.VENDOR_CATEGORY
                AND A.STANDARD_VENDOR_NAME=T.STANDARD_VENDOR_NAME)
ORDER BY A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME