民间。我似乎找不到这个问题的答案。我可以在SQL Server中完成,但我现在正在使用Access 2013,而我通常的SQL技巧似乎不起作用。
我需要创建一个课程成本v。收入摘要报告。
我有三个表:班级列表,成本列表,注册列表。成本和注册(成本和收入)都通过在所有表中标识该类的关键字段与类列表相关联。
我能够运行成本报告或收入报告,并且每个班级的总数都很好,但是当我将它们组合起来获得每个班级的净额时,成本会乘以注册报告中的行数反之亦然。
我尝试过使用Outer Join,但访问不喜欢它,即使在正确的位置使用[]也是如此。最好将其保持在访问状态,因为远离excel是重点。
这是糟糕结果背后的SQL。我知道这些连接是错误的,但我无法接受任何其他类型的连接。
SELECT DISTINCTROW Classes.ID,
Classes.Title,
Classes.Instructor,
Classes.Date,
Sum(Costs.Amount) AS [Sum Of Amount],
Sum(Registrations.Tuition) AS [Sum Of Tuition],
Count(*) AS [Count Of Classes]
FROM (Classes
LEFT JOIN Registrations ON Classes.[ID] = Registrations.[Class ID])
LEFT JOIN Costs ON Classes.[ID] = Costs.[Class ID]
GROUP BY Classes.ID,
Classes.Title,
Classes.Instructor,
Classes.Date;
有什么建议吗?提前谢谢。
答案 0 :(得分:0)
您需要两个单独的查询来汇总不同表的值,即使它们已连接到同一主表。否则,SQL的选择部分将在另外两个表上执行交叉连接,有效地为每个注册重新选择每个成本值。该选择过程在分组和聚合(即总和,计数)之前发生。这就是你得到乘以总和的原因。
DISTINCTROW无效,因为查询是根据连接中每个表的字段选择值,因此它必须有效地保留原始集中的每一行。 DISTINCTROW 不首先从一个表中选择行,然后从另一个表中独立选择行(也不单独对它们求和)。相反,应用完整选择和交叉连接,然后通过询问&#34来过滤掉行;此行是否仅包含来自已选择的源表行的数据?"如果答案是肯定的,则将其从最终选择中排除。但是,如果所选数据包含联接中每个表的值,则每一行都是唯一的,因此不会排除任何内容。
定义一个总和:
SELECT Classes.ID As ID,
Sum(Costs.Amount) AS [Sum Of Amount]
FROM Classes
LEFT JOIN Costs
ON Classes.[ID] = Costs.[Class ID]
GROUP BY Classes.ID
然后另一个:
SELECT Classes.ID As ID,
Sum(Registrations.Tuition) AS [Sum Of Tuition]
FROM Classes
LEFT JOIN Registrations ON Classes.[ID] = Registrations.[Class ID]
GROUP BY Classes.ID
您可以在Access中保存这些查询,然后按名称在其他查询中引用它们,或者您可以包含嵌入式SQL。在这种情况下,它只是个人偏好,但是使用可视化设计视图无法检查或编辑嵌入式查询,而是必须使用Access中的SQL视图进行编辑。
SELECT DISTINCTROW Classes.ID, Classes.Title,
Classes.Instructor, Classes.Date,
CostsAgg.[Sum Of Amount],
RegAggs.[Sum Of Tuition]
FROM (Classes LEFT JOIN
(SELECT Classes.ID As ID, Sum(Costs.Amount) AS [Sum Of Amount]
FROM Classes LEFT JOIN Costs ON Classes.[ID] = Costs.[Class ID]
GROUP BY Classes.ID) AS CostsAgg ON Classes.ID = CostsAgg.ID)
LEFT JOIN
(SELECT Classes.ID As ID, Sum(Registrations.Tuition) AS [Sum Of Tuition]
FROM Classes LEFT JOIN Registrations ON Classes.[ID] = Registrations.[Class ID]
GROUP BY Classes.ID) AS RegAggs
ON Classes.ID = RegAggs.ID
GROUP BY Classes.ID,
Classes.Title,
Classes.Instructor,
Classes.Date;
我没有包含Count列,因为从示例中不清楚你真正想要计算什么。您当然可以在任何子/查询中单独包含一个Count字段,或者在所有子/查询中分别包含一个Count字段,以获得不同的值。