MS Access 产品经理能力时间表 query/report
MS Access product manager capacity timeline query/report
这可能需要一些解释,但我想弄清楚这是否是一个我还没有弄清楚如何编写的查询,或者是否可以通过更改当前结构更好地解决这个问题我建立的 MS Access 数据库。所以说...
我有一个包含 3 个主要 table 的 MS Access 数据库来解决这个问题:
[Products]
[ProductChanges]
[Managers]
它们是这样链接的:
[Products].[ID] -> [ProductChanges].[PName]
[Products].[CurrManager] -> [Managers].[ID]
[ProductChanges].[CurrManager] -> [Managers].[ID]
Products table 列出了我们服务(或将要服务)的所有当前、过去和未来的产品,ProductChanges table 包含对该产品的所有更改(经理之间的变动、状态更新等)我已经让它从导航视图看起来非常漂亮,每个产品的表单显示其当前状态、经理,子表单显示其过去和即将发生的更改(来自 ProductChanges table)。
我还编写了一个更新查询,它会在每次打开数据库时运行,根据 ProductChanges table 中的更改日期更新 Products table 中的 CurrManager 字段,并将其更新为 ProductChanges table 中 CurrManager 字段的值。也许我应该更改其中一个字段名称,现在输入它听起来很混乱。
这是棘手的部分:随着新产品的出现,我们需要知道哪些经理可以承担更多(他们有最大容量)。当前容量很容易,查询 Products table 的字段 'CurrManager' 并计算分配给它们的产品的 ID,但我们需要看看将来谁有容量,最好以时间线格式。由于产品经常易手(有些产品完成并转移到其他地方),每个经理监督的产品数量将随着数据库根据 ProductChanges table.[=15= 中的日期自行更新而改变。 ]
因此,理想情况下最终输出的示例如下:
1/1/2016 | 1/8/2016 | 1/15/2016
Smith, J 10 12 9
取决于在这些日期之间有多少产品计划分配给 J. Smith 或从 J. Smith 转移。 A "Capacity by Week" 本质上。我取得了一些进展,但已经挂断了一段时间。此查询将为我提供一个基本的历史时间轴,但我似乎无法用它来总结日期范围的投资组合:
SELECT Managers.LastName
,Managers.FirstName
,ProductChanges.Effectivedate
,[ProductChanges].[EffectiveDate] - Weekday([ProductChanges].[EffectiveDate]) + 1 AS [Week Of]
,Count(Products.Name) AS NumProducts
FROM Managers
RIGHT JOIN (
Products INNER JOIN (
ProductChanges LEFT JOIN Managers AS Managers_1 ON ProductChanges.CurrManager = Managers_1.ID
) ON Products.ID = ProductChanges.InnCode
) ON Managers.ID = Products.CurrManager
,Managers.FirstName
,ProductChanges.Effectivedate
,[ProductChanges].[EffectiveDate] - Weekday([ProductChanges].[EffectiveDate]) + 1
HAVING (
((Managers.LastName) IS NOT NULL)
AND ((ProductChanges.Effectivedate) > 0)
)
ORDER BY Managers.LastName;
我知道这是一团糟,所以如果(以及何时)需要澄清,我会密切关注这一点。
考虑一个 crosstab query(一个独特的 MS Access SQL 查询,在其他 RDMS 中不可用)它沿值列(即有效日期)运行 旋转数据(计数、总和、平均值、最小值、最大值等)。
下面在聚合查询中加入所有三个 Managers、ProductChanges 和 Products 表。根据您的模式根据需要进行调整。在 MSAccess.exe 中,您可以在设计视图中调整交叉表,选择 行标题(一个或多个),列标题(只有一个)和 Value(只有一个)字段:
TRANSFORM Count(p.InnCode) AS NumProducts
SELECT m.LastName, m.FirstName
FROM (Managers m
INNER JOIN ProductChanges pc
ON m.[ID] = pc.[CurrManager])
INNER JOIN Products p
ON pc.[PName] = p.[ID]
GROUP BY m.LastName, m.FirstName
PIVOT pc.Effectivedate
请注意:MS Access tables/queries 有 255 列的限制。所以如果你 运行 进入超过 254 个唯一日期,你将需要过滤哪些可以用 PIVOT Column IN()
子句处理。甚至考虑通过 VBA 参数在接下来的 3-4 周内动态传递电流。
TRANSFORM Count(p.InnCode) AS NumProducts
SELECT m.LastName, m.FirstName
FROM (Managers m
INNER JOIN ProductChanges pc
ON m.[ID] = pc.[CurrManager])
INNER JOIN Products p
ON pc.[PName] = p.[ID]
GROUP BY m.LastName, m.FirstName
PIVOT pc.Effectivedate IN ('1/1/2016', '1/8/2016', '1/15/2016')
最简单的方法是查询您的 table 并添加一个将日期转换为 "week of" 的字段,类似于您对
所做的
ProductChanges.EffectiveDate - Weekday(ProductChanges.EffectiveDate) + 1
从那时起,这只是按此字段分组的简单查询 - 在加入所有其他 table 之后,您需要对 ProductChanges table.
我知道了!它最终是一个两步过程来完成我需要它做的事情,但只要产品更改的记录是最新的,这就向我展示了经理获得和失去产品的实际时间表。
我必须这样做的主要原因是用户可以更改产品的过去历史,以防万一缺少某些内容,这意味着 ProductChanges 中的记录 ID table相对于 EffectiveDate 字段,可以认为本质上是随机的,因此仅对 ProductChanges table 进行 运行 总查询对于产品更改历史已更改的经理来说几乎但不是很有效。我编写了一个快速脚本来构建一个 table 专门用于按我需要的方式订购 ID:
Dim db As Database
Set db = CurrentDB
db.Execute "DROP TABLE GainLoss;"
db.Execute "CREATE TABLE GainLoss(AutoID AutoIncrement, HCID Long, MgrID Long, LastName varchar(100), FirstName varchar(100), HCDate Date, GainLoss Long)"
db.Execute "INSERT INTO GainLoss(HCID, MgrID, LastName, FirstName, HCDate, GainLoss) SELECT hc.ID, s.ID, s.LastName, s.FirstName, hc.EffectiveDate, iif(s.id = hc.currmanager,1,-1) FROM Managers s INNER JOIN ProductChanges hc ON (s.ID = hc.currmanager OR s.ID = hc.prevmanager) ORDER BY LastName, FirstName, EffectiveDate;"
这也让我对经理获得的每件产品加一分,对他们传递的每件产品减一分。通过此查询抛出:
SELECT A.AutoID, A.MgrID, A.LastName, A.FirstName, A.HCDate, Sum(B.GainLoss) AS Capacity
FROM GainLoss AS A LEFT JOIN GainLoss AS B ON (A.AutoID >= B.AutoID) AND (A.MgrID = B.MgrID) AND (A.HCDate >= B.HCDate)
GROUP BY A.LastName, A.FirstName, A.MgrID, A.HCDate, A.AutoID;
并且您有一个时间轴,其中显示了向经理的投资组合添加或减少产品的每项更改。
这可能需要一些解释,但我想弄清楚这是否是一个我还没有弄清楚如何编写的查询,或者是否可以通过更改当前结构更好地解决这个问题我建立的 MS Access 数据库。所以说...
我有一个包含 3 个主要 table 的 MS Access 数据库来解决这个问题:
[Products]
[ProductChanges]
[Managers]
它们是这样链接的:
[Products].[ID] -> [ProductChanges].[PName]
[Products].[CurrManager] -> [Managers].[ID]
[ProductChanges].[CurrManager] -> [Managers].[ID]
Products table 列出了我们服务(或将要服务)的所有当前、过去和未来的产品,ProductChanges table 包含对该产品的所有更改(经理之间的变动、状态更新等)我已经让它从导航视图看起来非常漂亮,每个产品的表单显示其当前状态、经理,子表单显示其过去和即将发生的更改(来自 ProductChanges table)。
我还编写了一个更新查询,它会在每次打开数据库时运行,根据 ProductChanges table 中的更改日期更新 Products table 中的 CurrManager 字段,并将其更新为 ProductChanges table 中 CurrManager 字段的值。也许我应该更改其中一个字段名称,现在输入它听起来很混乱。
这是棘手的部分:随着新产品的出现,我们需要知道哪些经理可以承担更多(他们有最大容量)。当前容量很容易,查询 Products table 的字段 'CurrManager' 并计算分配给它们的产品的 ID,但我们需要看看将来谁有容量,最好以时间线格式。由于产品经常易手(有些产品完成并转移到其他地方),每个经理监督的产品数量将随着数据库根据 ProductChanges table.[=15= 中的日期自行更新而改变。 ]
因此,理想情况下最终输出的示例如下:
1/1/2016 | 1/8/2016 | 1/15/2016
Smith, J 10 12 9
取决于在这些日期之间有多少产品计划分配给 J. Smith 或从 J. Smith 转移。 A "Capacity by Week" 本质上。我取得了一些进展,但已经挂断了一段时间。此查询将为我提供一个基本的历史时间轴,但我似乎无法用它来总结日期范围的投资组合:
SELECT Managers.LastName
,Managers.FirstName
,ProductChanges.Effectivedate
,[ProductChanges].[EffectiveDate] - Weekday([ProductChanges].[EffectiveDate]) + 1 AS [Week Of]
,Count(Products.Name) AS NumProducts
FROM Managers
RIGHT JOIN (
Products INNER JOIN (
ProductChanges LEFT JOIN Managers AS Managers_1 ON ProductChanges.CurrManager = Managers_1.ID
) ON Products.ID = ProductChanges.InnCode
) ON Managers.ID = Products.CurrManager
,Managers.FirstName
,ProductChanges.Effectivedate
,[ProductChanges].[EffectiveDate] - Weekday([ProductChanges].[EffectiveDate]) + 1
HAVING (
((Managers.LastName) IS NOT NULL)
AND ((ProductChanges.Effectivedate) > 0)
)
ORDER BY Managers.LastName;
我知道这是一团糟,所以如果(以及何时)需要澄清,我会密切关注这一点。
考虑一个 crosstab query(一个独特的 MS Access SQL 查询,在其他 RDMS 中不可用)它沿值列(即有效日期)运行 旋转数据(计数、总和、平均值、最小值、最大值等)。
下面在聚合查询中加入所有三个 Managers、ProductChanges 和 Products 表。根据您的模式根据需要进行调整。在 MSAccess.exe 中,您可以在设计视图中调整交叉表,选择 行标题(一个或多个),列标题(只有一个)和 Value(只有一个)字段:
TRANSFORM Count(p.InnCode) AS NumProducts
SELECT m.LastName, m.FirstName
FROM (Managers m
INNER JOIN ProductChanges pc
ON m.[ID] = pc.[CurrManager])
INNER JOIN Products p
ON pc.[PName] = p.[ID]
GROUP BY m.LastName, m.FirstName
PIVOT pc.Effectivedate
请注意:MS Access tables/queries 有 255 列的限制。所以如果你 运行 进入超过 254 个唯一日期,你将需要过滤哪些可以用 PIVOT Column IN()
子句处理。甚至考虑通过 VBA 参数在接下来的 3-4 周内动态传递电流。
TRANSFORM Count(p.InnCode) AS NumProducts
SELECT m.LastName, m.FirstName
FROM (Managers m
INNER JOIN ProductChanges pc
ON m.[ID] = pc.[CurrManager])
INNER JOIN Products p
ON pc.[PName] = p.[ID]
GROUP BY m.LastName, m.FirstName
PIVOT pc.Effectivedate IN ('1/1/2016', '1/8/2016', '1/15/2016')
最简单的方法是查询您的 table 并添加一个将日期转换为 "week of" 的字段,类似于您对
所做的ProductChanges.EffectiveDate - Weekday(ProductChanges.EffectiveDate) + 1
从那时起,这只是按此字段分组的简单查询 - 在加入所有其他 table 之后,您需要对 ProductChanges table.
我知道了!它最终是一个两步过程来完成我需要它做的事情,但只要产品更改的记录是最新的,这就向我展示了经理获得和失去产品的实际时间表。
我必须这样做的主要原因是用户可以更改产品的过去历史,以防万一缺少某些内容,这意味着 ProductChanges 中的记录 ID table相对于 EffectiveDate 字段,可以认为本质上是随机的,因此仅对 ProductChanges table 进行 运行 总查询对于产品更改历史已更改的经理来说几乎但不是很有效。我编写了一个快速脚本来构建一个 table 专门用于按我需要的方式订购 ID:
Dim db As Database
Set db = CurrentDB
db.Execute "DROP TABLE GainLoss;"
db.Execute "CREATE TABLE GainLoss(AutoID AutoIncrement, HCID Long, MgrID Long, LastName varchar(100), FirstName varchar(100), HCDate Date, GainLoss Long)"
db.Execute "INSERT INTO GainLoss(HCID, MgrID, LastName, FirstName, HCDate, GainLoss) SELECT hc.ID, s.ID, s.LastName, s.FirstName, hc.EffectiveDate, iif(s.id = hc.currmanager,1,-1) FROM Managers s INNER JOIN ProductChanges hc ON (s.ID = hc.currmanager OR s.ID = hc.prevmanager) ORDER BY LastName, FirstName, EffectiveDate;"
这也让我对经理获得的每件产品加一分,对他们传递的每件产品减一分。通过此查询抛出:
SELECT A.AutoID, A.MgrID, A.LastName, A.FirstName, A.HCDate, Sum(B.GainLoss) AS Capacity
FROM GainLoss AS A LEFT JOIN GainLoss AS B ON (A.AutoID >= B.AutoID) AND (A.MgrID = B.MgrID) AND (A.HCDate >= B.HCDate)
GROUP BY A.LastName, A.FirstName, A.MgrID, A.HCDate, A.AutoID;
并且您有一个时间轴,其中显示了向经理的投资组合添加或减少产品的每项更改。