每组前 3 名,包括 0
Posted
技术标签:
【中文标题】每组前 3 名,包括 0【英文标题】:Top 3 per group including 0 【发布时间】:2015-10-27 17:19:21 【问题描述】:我有一个表,我希望从 Access 2010 开始,每周按 ErrorMargin 返回前 3 条记录。
我遇到的问题是 0 值被忽略了,我希望在平局的情况下只看到 1 条记录,而平局的记录总数超过 3。
我拥有的表格是:注意:帖子底部的 VBA 用于创建表格。
TMID WeekCommencing ErrorMargin
1 05-Oct-15 0
1 12-Oct-15 2
3 05-Oct-15 1
3 12-Oct-15 1
8 12-Oct-15 2
9 05-Oct-15 0.333333333
9 12-Oct-15 4
12 05-Oct-15 0
12 12-Oct-15 1.5
我现在的SQL是:
SELECT T1.TMID,
T1.WeekCommencing,
T1.ErrorMargin,
COUNT(*)
FROM qry_REP_ErrorMargin T1 INNER JOIN qry_REP_ErrorMargin T2 ON
T1.ErrorMargin <= T2.ErrorMargin AND
T1.WeekCommencing = T2.WeekCommencing
GROUP BY T1.TMID,
T1.WeekCommencing,
T1.ErrorMargin
HAVING COUNT(*) <= 3
ORDER BY T1.WeekCommencing,
T1.ErrorMargin
这将返回下表,该表仅显示 2015 年 5 月 10 日的两条记录 - 还有两条 ErrorMargin 为 0 的记录,我希望它也返回其中一条。哪个没关系。 TMID 和 WeekCommencing 字段将构成该表的关键字段。
TMID WeekCommencing ErrorMargin Expr1003
9 05/10/2015 0.33 2
3 05/10/2015 1 1
1 12/10/2015 2 3
8 12/10/2015 2 3
9 12/10/2015 4 1
我尝试过其他解决方案,但还没有成功 - MS Access Select top n query grouped by multiple fields
创建表格的VBA代码:
Sub Create()
Dim db As DAO.Database
Set db = CurrentDb
db.Execute "CREATE TABLE qry_REP_ErrorMargin" & _
"(TMID LONG, WeekCommencing DATE, ErrorMargin Double)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (1,42282,0)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (1,42289,2)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (3,42282,1)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (3,42289,1)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (8,42289,2)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (9,42282,0.333333333333333)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (9,42289,4)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (12,42282,0)"
db.Execute "INSERT INTO qry_REP_ErrorMargin" & _
"(TMID, WeekCommencing, ErrorMargin) VALUES (12,42289,1.5)"
End Sub
【问题讨论】:
为什么9 | 05/10/2015 | 0.33 | 2
有 count = 2 ??
顺便说一句,您的查询使用您的数据返回不同的结果sqlfiddle.com/#!6/00f48/1
什么意思 top 3 for group
因为你说不关心 0 先走。你应该有双 0. 然后是 0.333
感谢您的 cmets Juan。我不明白您所说的计数为 2 的记录是什么意思,我认为 sqlfiddle 执行 SQL 的方式与 Access 的执行方式不同,因为它给出了不同的结果。你是对的 - 10 月 5 日应该有 0、0 和 0.333,但正如我在帖子中所说的 - 它忽略了 0,它不应该是。
【参考方案1】:
以下可能会做你想做的事:
SELECT em.*
FROM qry_REP_ErrorMargin as em
WHERE em.TMID IN (SELECT TOP 3 TMID
FROM qry_REP_ErrorMargin as em2
WHERE em2.WeekCommencing = em.WeekCommencing
ORDER BY em2.ErrorMargin
);
请注意,在平局的情况下,MS Access 可能会返回三行以上。如果您不想重复,则在 ORDER BY
中包含一个 id 列以防止出现平局:
ORDER BY em2.ErrorMargin, em2.TMID
【讨论】:
谢谢戈登。使用 ID 列上的额外ORDER BY
,它返回的正是我想要的 - 带有示例数据。只需要使用各种数据集对其进行测试,我会在几个小时后回复以接受答案。以上是关于每组前 3 名,包括 0的主要内容,如果未能解决你的问题,请参考以下文章