如何获得要在交叉表查询的多列中计数的记录?

How can I get a record to be counted in multiple columns of a Crosstab Query?

背景资料:

  1. 我的公司要求员工在一个职位上至少持有一份证书(cert)。一个员工总共可以获得17种不同的认证。

  2. 一个员工可以持有多个证书。但是在任何一天,他们只能 "sit" 他们获得认证的职位之一。大多数员工主要担任他们持有证书的最高级别职位,但如果人员短缺,可以担任较低级别的职位在那个职位上,如果他们持有那个特定的证书(一些员工来找我们持有更高级别的证书,但 none 持有较低级别的证书,因为他们让它们过期)。

  3. 多名员工可以持有同一份证书。

  4. 大约 90% 的员工有合同,这意味着他们有一个固定的终止日期。合同可以延期,但为了这个 Access 数据库和要生成的报告,我们假设终止日期是一成不变的。

我的老板(和老板的老板)想要整理一份人员配置预测报告,这样他们就不会在我们开始运行任何一个职位的认证员工不足时措手不及。

他们想要的例子:

假设您有三名员工:

假设我的老板想要预测 12 个月,起始月份为 2019 年 11 月(他只能 select 等于或晚于当前月份的起始月份-年)。下面的图表是在子报表中生成的,应该是根据上述员工信息生成的。

所有认证图表

+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   Cert    | Nov 19 | Dec 19 | Jan 20 | Feb 20 | Mar 20 | Apr 20 | May 20 | Jun 20 | Jul 20 | Aug 20 | Sep 20 | Oct 20 |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| Position1 |      2 |      3 |      3 |      3 |      3 |      3 |      3 |      2 |      2 |      2 |      2 |      2 |
| Position2 |      2 |      2 |      2 |      2 |      2 |      2 |      2 |      1 |      1 |      1 |      1 |      1 |
| Position3 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      0 |      0 |      0 |      0 |      0 |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+

初级认证图表

+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   Cert    | Nov 19 | Dec 19 | Jan 20 | Feb 20 | Mar 20 | Apr 20 | May 20 | Jun 20 | Jul 20 | Aug 20 | Sep 20 | Oct 20 |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| Position1 |      0 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |
| Position2 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |
| Position3 |      1 |      1 |      1 |      1 |      1 |      1 |      1 |      0 |      0 |      0 |      0 |      0 |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+

现在我已经有了一个解决方案,但它极其效率低下并且涉及对每个单元格的查询(2 个图表 X 12 个月 X 17 个位置 = 408 个查询,当报告是产生)。我希望通过交叉表查询做一些更有效率的事情。

表格是这样设置的(只列出相关字段):

Emp_table

Cert_individual

cert_table

显然我需要做一些 INNER JOINS 才能将所有内容放在一起,我尝试使用 this website 中的格式进行交叉表查询,但它只会添加一个单独的证书计算员工收到证书的月份和年份,而不是员工持有证书的每个月。

所以我的问题是:

在 SQL 或 VBA 中是否有一种方法可以根据员工收到证书的时间以及他们的合同安排的时间跨多个列(月-年)计算证书终止?

据我所知,获取交叉表查询的主要问题是它只能生成包含您已有数据的列。

获取每月列的解决方案是在一侧 table 包含 12 个日期,然后使用笛卡尔积为认证中的每条记录生成每月数据 table。这个“日期”table 可以更新和维护,以匹配您在报告中使用查询所需的月份。


例如,如果您有一个名为 TempDates 的 table :

还有一个 table 和 Employees 以及以下数据:

您可以使用我命名为 QryCertsDates 的查询生成笛卡尔积:

SELECT Employees.*, TempDates.* FROM TempDates, Employees;

这让您可以将所有想要的日期与 table Employees 中的原始日期附加在一起,以获得类似于以下的数据:

现在您可以生成以月份和年份为中心的交叉表查询,并使用 WHERE 条件过滤日期,例如:

TRANSFORM Count(QryCertsDates.Cert) AS CountOfCert SELECT QryCertsDates.Cert FROM QryCertsDates WHERE (((CDate([Yr] & "-" & [Mo])) Between CDate([Start]) And CDate([Expire]))) GROUP BY QryCertsDates.Cert PIVOT CDate([Yr] & "-" & Format([Mo],"00"));

你最终会得到这样的结果:

您也可以做同样的事情来获得第二个 table/report。我不知道你的数据库结构,所以你很可能需要做一些调整。获得类似结果的另一种可能方法是使用 VBA.

填写 table

但是,这可能是更容易实施的解决方案。祝你好运!