【问题标题】:Convert rows to columns for a Report将行转换为报表的列
【发布时间】:2015-05-05 13:44:17
【问题描述】:

使用找到的说明here 我尝试创建一个交叉表查询来显示前三年的历史数据,我想将其输出到报告中。

我遇到了一些复杂情况,这让我很难做到这一点,而且我无法正确显示数据。

它所基于的查询结构如下:

EmpID | ReviewYearID | YearName | ReviewDate  | SelfRating | ManagerRating | NotSelfRating |
  1   |      5       |   2013   | 01/09/2013  |    3.5     |      3.5      |      3.5      |
  1   |      6       |   2014   | 01/09/2014  |    2.5     |      2.5      |      2.5      |
  1   |      7       |   2015   | 01/09/2015  |    4.5     |      4.5      |      4.5      |
  2   |      6       |   2014   | 01/09/2014  |    2.0     |      2.0      |      2.0      |
  2   |      7       |   2015   | 01/09/2015  |    2.0     |      2.0      |      2.0      |
  3   |      7       |   2015   | 01/09/2015  |    5.0     |      5.0      |      5.0      |

[编辑]:这是基本查询的 SQL。它正在合并来自两个表的数据:

SELECT tblEmployeeYear.EmployeeID AS EmpID, tblReviewYear.ID AS ReviewYearID, tblReviewYear.YearName, tblReviewYear.ReviewDate, tblEmployeeYear.SelfRating, tblEmployeeYear.ManagerRating, tblEmployeeYear.NotSelfRating
FROM tblReviewYear INNER JOIN tblEmployeeYear ON tblReviewYear.ID = tblEmployeeYear.ReviewYearID;

[/编辑]

我想要一个交叉表查询,它可以转换列/行以显示特定员工最多 3 年的历史数据(基于审查日期)。员工 ID 1 的最终结果如下所示:

Year          |  2015  |  2014  |  2013  |
SelfRating    |  4.5   |  2.5   |  3.5   |
ManagerRating |  4.5   |  2.5   |  3.5   |
NotSelfRating |  4.5   |  2.5   |  3.5   |

其他员工的列会更少,因为他们没有前几年的数据。

我在将其过滤到特定员工并按审核日期对年份进行排序时遇到问题(名称并不总是一种可靠的排序方式)。

最后我希望将其用作报告的数据。

如果有与交叉表查询不同的方法来完成此操作,我也可以。

谢谢!

【问题讨论】:

  • 你很想看看 sql PIVOT 语句technet.microsoft.com/en-us/library/… 恐怕我帮不了你更多,因为我自己从来没有真正使用过它,但是我 99% 确定这可以满足您的需求
  • 您是否考虑过将初始查询链接到 Excel 工作表,然后在 Excel 中创建数据透视表?这是我从您的初始查询drive.google.com/file/d/0B-J5B7nFljZiMUYzZzAtTE5PeHc/… 在 Excel 中创建的内容,这可以链接到您的 Access 查询,因此如果有新数据,您可以在 Excel 中刷新它。如果这是您所追求的,但不知道该怎么做,请告诉我,我会发布详细的答案。
  • @MattHall - 当表单加载时,该过程可以自动发生吗?基本上,我希望用户能够选择一名员工并将该数据作为他们需要在表单上执行的其他操作的参考。我正计划将报告嵌入到表单中。

标签: sql ms-access vba ms-access-2013


【解决方案1】:

所有评级类型都需要一个列,而不是每个类型的单独列。如果您不能重新设计表格,我建议您为您的目的创建一个新表格。下面使用联合来添加上述类型列。您创建一个列并对值进行硬编码(SelfRating、ManagerRating 等):

SELECT * INTO EmployeeRatings
FROM (SELECT tblEmployeeYear.EmployeeId AS EmpId, ReviewYearId, "SelfRating" AS Category, SelfRating AS Score
      FROM tblEmployeeYear
      WHERE SelfRating Is Not Null
      UNION ALL
      SELECT tblEmployeeYear.EmployeeId, ReviewYearId, "ManagerRating", ManagerRating
      FROM tblEmployeeYear
      WHERE ManagerRating Is Not Null
      UNION ALL
      SELECT tblEmployeeYear.EmployeeId, ReviewYearId, "NotSelfRating", NotSelfRating
      FROM tblEmployeeYear
      WHERE NotSelfRating Is Not Null)

然后使用新创建的表代替 tblEmployeeYear。请注意,我使用Year([ReviewDate]),它只会返回年份。此外,由于看起来每年每种评论类型可能不止一个,因此我对这一年的 Score 进行了平均。

TRANSFORM Avg(Score)
SELECT EmpId, Category
FROM (SELECT EmpId, Category, ReviewDate, Score
      FROM tblReviewYear 
      INNER JOIN EmployeeRatings
              ON tblReviewYear.ID = EmployeeRatings.ReviewYearID) AS Reviews
GROUP BY EmpId, Category
PIVOT Year([ReviewDate]);

【讨论】:

  • 嗨,迈克 - 澄清初始数据来自一个查询,我在尝试将其转换为我需要的格式之前将两个表中的数据组合在一起。审查年份存储在一个表格中,然后有一个表格用于每年的员工数据。如果有帮助,我将编辑问题以包含基本查询的 SQL。也许我只需要更改我的基本查询以使交叉表查询更简单?
  • @icouper 我认为很难避免更改表格或重新创建表格。我用另一种可能的解决方案更新了我的答案
  • 好的,我认为这让我更接近了。我将 PIVOT 的 [ReviewDate] 替换为 [YearName] ,因为在这种情况下日期并没有真正的帮助。但是我希望首先显示最近的一年 - 有没有办法根据 [ReviewDate] 对列进行排序,同时将 [YearName] 显示为标题?
  • 我相信它默认按升序(从左到右)排序,但如果你想按降序排序,请尝试在GROUP BY EmpId, Category 之后添加ORDER BY YearName DESC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 2018-01-17
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 2016-03-16
相关资源
最近更新 更多