多个数据点的交叉表查询

Posted

技术标签:

【中文标题】多个数据点的交叉表查询【英文标题】:Crosstab Query on multiple data points 【发布时间】:2017-10-03 15:20:38 【问题描述】:

我有一个跟踪员工质量评估数据的表格。它包括员工姓名、跟踪重要项目的 5 个是/否字段以及用户执行每项任务的日期作为列标题。每个员工每月获得 10 条记录,因此它包含大量数据,说明我们的员工在这 5 项任务中的表现如何。

我想要一份报告,显示这 5 个是/否字段的月平均值:上诉、NRP、流失、协议和重新订阅。我希望那些成为行标题。我希望列标题是连续的月份,平均值是值。我可以对单个项目进行交叉表查询,例如将 avg:Appeal 作为值,将用户作为行标题。如何构建查询以使用所有 5 个是/否字段?他们希望结果是这样的:

Table image showing how I want it to look

对正确答案的评论: June7 想出了一个很好的答案!我在 DataUNION 查询中将 True 更改为 False,因为我想要 Accuracy 百分比,而 true 表示员工评估错误。我还添加了一些我之前没有提到的字段。非常感谢您帮助清理 June7!阅读您所写的内容启发了我开始学习关于 Lynda 的 SQL 课程。我知道它是基本的,但你必须从某个地方开始,我已经到了 access 的内置函数不适合我的地步。希望通过下一个问题,我能够解决下面评论员的担忧,他们对我没有首先尝试过的代码感到不安。 June7's revised Code

【问题讨论】:

答案只能是是的,有可能。你需要问一个可以回答的问题。请参阅How to Ask 并创建一个minimal reproducible example。如果没有输入数据,我们所能做的就是猜测您当前的尝试和预期输出。 阅读 mso post 了解关于 sql 查询的好问题应该是什么样的,然后阅读 edit 你的问题。它还有一些指向其他指南的有用链接,例如 dba.blogoverflow.com/2012/06/help-us-help-you。使用它,应用它。您无法通过评论来解决您的问题。 如果是/否字段是数据中的列,如果您希望它们成为最终交叉表上的行,则需要规范化数据以将每个问题放在单独的记录中。不过,如上所述 - 这只是一个有根据的猜测,没有更好的关于表格布局和其他重要细节的问题。 感谢唐乔治的回复!您是正确的,因为该表包括(除其他外)我列出的 5 个字段和日期作为列。我认为您要说的是创建另一个表,将每个是/否变成单独的记录?我在想的是 3 个列标题为:Nate Date、对 5 个字段的查找以及是/否的值?然后我可以交叉表,所以行标题是查找,列标题是日期,值是是/否的平均值。 再次:How to ask a good SQL question。样本数据和预期结果比文字描述有用得多。使用this 提供可读数据。 【参考方案1】:

考虑:

查询 1:数据联合

SELECT ID AS SourceID, Emp, Year([TaskDate]) AS Yr, Format([TaskDate], "mmm") AS Mo, "Appeal" AS Trend 
      FROM Data 
      WHERE Appeal=True
UNION SELECT ID, Emp, Year([TaskDate]), Format([TaskDate], "mmm"), "NRP" 
      FROM Data WHERE NRP = True
UNION SELECT ID, Emp, Year([TaskDate]), Format([TaskDate], "mmm"), "Churn" 
      FROM Data WHERE Churn = True
UNION SELECT ID, Emp, Year([TaskDate]), Format([TaskDate], "mmm"), "Protocol" 
      FROM Data WHERE Protocol = True
UNION SELECT ID, Emp, Year([TaskDate]), Format([TaskDate], "mmm"), "Resub" 
      FROM Data WHERE Resub = True;

查询 2:数据计数

SELECT DataUNION.Yr, DataUNION.Mo, DataUNION.Trend, 
Count(DataUNION.Emp) AS CountOfEmp, Q.CntYrMo, Count([Emp])/[CntYrMo]*100 AS Pct
FROM (SELECT Year([TaskDate]) AS Yr, Format([TaskDate],"mmm") AS Mo, Count(Data.ID) AS CntYrMo
      FROM Data
      GROUP BY Year([TaskDate]), Format([TaskDate],"mmm")) AS Q 
INNER JOIN DataUNION ON (Q.Yr = DataUNION.Yr) AND (Q.Mo = DataUNION.Mo)
GROUP BY DataUNION.Yr, DataUNION.Mo, DataUNION.Trend, Q.CntYrMo;

查询3:

TRANSFORM First(DataCount.Pct) AS FirstOfPct
SELECT DataCount.Yr, DataCount.Trend
FROM DataCount
GROUP BY DataCount.Yr, DataCount.Trend
PIVOT DataCount.Mo In ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");

【讨论】:

June7,太棒了!非常感谢您的代码。我对 SQL 了解不多,所以你真的帮助了我。我在上面附上了您的代码的屏幕截图。您能否就将计数转换为总记录百分比的最佳方法提出建议?例如:6 月份对 1236 条记录进行了 4 次上诉检查。 年/月百分比? 6月份有1236条记录?只有 4 人上诉? 正确。这些实际上是医疗记录,因此低于 98% 的准确度被认为是不可接受的。 看看你是否喜欢修改后的查询。 效果很好!我更新了上面的问题,以便我可以链接图像并将您标记为答案。再次感谢您!

以上是关于多个数据点的交叉表查询的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE怎么用SQL查询多张表和多个时间点的数据的行数?

MS Access:对多个表的交叉表查询(多对多关系)

详解SQL Server连接(内连接外连接交叉连接)

数据表视图中的 MS Access 表单交叉表查询

SQL的连接(外连接内连接交叉连接和自连接)

MSSQL 详解SQL Server连接(内连接外连接交叉连接)