在一个查询中返回多个组中的前“X”条记录

Posted

技术标签:

【中文标题】在一个查询中返回多个组中的前“X”条记录【英文标题】:Return top 'X' records within multiple groups in one query 【发布时间】:2019-01-15 11:40:04 【问题描述】:

我有一个跨多个月的记录列表,即 9 月、10 月、11 月等,我需要在同一个查询中按每个月的计数返回前 10 个结果。到目前为止,我有以下内容:

SELECT [Financial Year] & "Resolved" & [Text Month] & [SegmentDescriptionST] AS [Key], "FY" & IIf(Month([MinOfResolvedDate])<10,Year([MinOfResolvedDate]),Year([MinOfResolvedDate])+1) AS [Financial Year], "Resolved" AS Metric, Format([MinOfResolvedDate],"mmm-yy") AS [Resolved Month], Format([MinOfResolvedDate],"mmm") AS [Text Month], Content_Accuracy_q.SegmentDescriptionST, Count(Content_Accuracy_q.SegmentDescriptionST) AS Amount

FROM Content_Accuracy_q

WHERE (((([Content_Accuracy_q].[MinOfResolvedDate]) Between #9/1/2018# And (DateSerial(Year(Date()),Month(Date()),0))) In 
    (SELECT TOP 10 Content_Accuracy_q.SegmentDescriptionST

    FROM Content_Accuracy_q

    Where ((Content_Accuracy_q.[Level 3 - Issue ST])="Inaccurate Information" Or (Content_Accuracy_q.[Level 3 - Issue ST])="Change of accommodation") AND ((Content_Accuracy_q.[Level 4 - Reason ST])<>"Cost"))))
    GROUP BY "FY" & IIf(Month([MinOfResolvedDate])<10,Year([MinOfResolvedDate]),Year([MinOfResolvedDate])+1), "Resolved", Format([MinOfResolvedDate],"mmm-yy"), Format([MinOfResolvedDate],"mmm"), Content_Accuracy_q.SegmentDescriptionST

    HAVING (((Content_Accuracy_q.SegmentDescriptionST)<>""))

    ORDER BY Format([MinOfResolvedDate],"mmm-yy") DESC , Count(Content_Accuracy_q.SegmentDescriptionST) DESC)

ORDER BY Format([MinOfResolvedDate],"mmm-yy") DESC , Count(Content_Accuracy_q.SegmentDescriptionST) DESC;

但是,我不断收到“ORDER BY 子句中的语法错误”并且无法超越这一点。有没有人能够成功运行与此类似的查询并在所需的几个月内按计数返回前“X”个结果?

【问题讨论】:

"mysql" 不是"ms 访问"。它们是两种完全不同的产品。关注 MySQL 标签的人可能对有关 Access 的问题不感兴趣(除非他们碰巧在这两个方面都有专长)。请在使用之前阅读标签定义,谢谢:-)。还请提供一些示例数据和预期结果,以便人们更容易理解您的数据结构和上下文。 【参考方案1】:

在使用缩进格式化 SQL 时,您的代码中有一些奇怪之处:

SELECT 
    [Financial Year] & "Resolved" & [Text Month] & [SegmentDescriptionST] AS [Key], 
    "FY" & IIf(Month([MinOfResolvedDate])<10,Year([MinOfResolvedDate]),Year([MinOfResolvedDate])+1) AS [Financial Year], 
    "Resolved" AS Metric, 
    Format([MinOfResolvedDate],"mmm-yy") AS [Resolved Month], 
    Format([MinOfResolvedDate],"mmm") AS [Text Month], 
    Content_Accuracy_q.SegmentDescriptionST, 
    Count(Content_Accuracy_q.SegmentDescriptionST) AS Amount
FROM 
    Content_Accuracy_q
WHERE 
    (
        (
            (
                [Content_Accuracy_q].[MinOfResolvedDate] BETWEEN #9/1/2018# AND DateSerial(Year(Date()),Month(Date()),0)
            )
            IN 
            (
                SELECT TOP 10 Content_Accuracy_q.SegmentDescriptionST
                FROM Content_Accuracy_q
                WHERE 
                (
                    Content_Accuracy_q.[Level 3 - Issue ST] = "Inaccurate Information" OR 
                    Content_Accuracy_q.[Level 3 - Issue ST] = "Change of accommodation"
                )
                AND 
                Content_Accuracy_q.[Level 4 - Reason ST] <> "Cost"
            )
        )
    )
GROUP BY 
    "FY" & IIf(Month([MinOfResolvedDate])<10,Year([MinOfResolvedDate]),Year([MinOfResolvedDate])+1), 
    "Resolved", 
    Format([MinOfResolvedDate],"mmm-yy"), 
    Format([MinOfResolvedDate],"mmm"), 
    Content_Accuracy_q.SegmentDescriptionST
HAVING 
    Content_Accuracy_q.SegmentDescriptionST <> ""
ORDER BY 
    Format([MinOfResolvedDate],"mmm-yy") DESC, 
    Count(Content_Accuracy_q.SegmentDescriptionST) DESC)
ORDER BY 
    Format([MinOfResolvedDate],"mmm-yy") DESC,
    Count(Content_Accuracy_q.SegmentDescriptionST) DESC;

首先,明显的错误是您的第一个 order by 子句中有一个不平衡的括号:

ORDER BY 
    Format([MinOfResolvedDate],"mmm-yy") DESC, 
    Count(Content_Accuracy_q.SegmentDescriptionST) DESC)
                                                       ^------- here

但是你也有两个order by 子句,这是无效的语法:

ORDER BY 
    Format([MinOfResolvedDate],"mmm-yy") DESC, 
    Count(Content_Accuracy_q.SegmentDescriptionST) DESC)
ORDER BY 
    Format([MinOfResolvedDate],"mmm-yy") DESC, 
    Count(Content_Accuracy_q.SegmentDescriptionST) DESC;

having 子句也似乎是多余的,因为标准没有引用聚合结果的字段:

HAVING 
    Content_Accuracy_q.SegmentDescriptionST <> ""

因此,可以将此标准作为where 子句的一部分包含在内:

FROM 
    Content_Accuracy_q
WHERE 
    Content_Accuracy_q.SegmentDescriptionST <> "" AND

但是,看看你的 where 子句,我觉得这句话没有意义:

(
    [Content_Accuracy_q].[MinOfResolvedDate] BETWEEN #9/1/2018# AND DateSerial(Year(Date()),Month(Date()),0)
)
IN 
(
    SELECT TOP 10 Content_Accuracy_q.SegmentDescriptionST
    FROM Content_Accuracy_q
    WHERE 
    (
        Content_Accuracy_q.[Level 3 - Issue ST] = "Inaccurate Information" OR 
        Content_Accuracy_q.[Level 3 - Issue ST] = "Change of accommodation"
    )
    AND 
    Content_Accuracy_q.[Level 4 - Reason ST] <> "Cost"
)

这里的代码是:

“选择[Content_Accuracy_q].[MinOfResolvedDate] BETWEEN #9/1/2018# AND DateSerial(Year(Date()),Month(Date()),0)的结果是SELECT TOP 10 Content_Accuracy_q.SegmentDescriptionST ...返回的结果之一的记录”

但表达式:

[Content_Accuracy_q].[MinOfResolvedDate] BETWEEN #9/1/2018# AND DateSerial(Year(Date()),Month(Date()),0)

将返回一个布尔值(即True/False-1/0);我猜你不打算检查布尔值是否是子查询返回的结果的成员。

【讨论】:

以上是关于在一个查询中返回多个组中的前“X”条记录的主要内容,如果未能解决你的问题,请参考以下文章

查询以显示每个用户提交的最少 3 条记录的前 3 条记录?

SQL 查询 - 返回连接表的前两条记录的连接

SQL如何显示查询结果的前100条?

oracle中如何只查询一条复合条件的记录,即查到一条记录就返回

SQL中显示查询结果的前几条记录

SQLite:仅返回每组中的前 2 个结果