为啥我的 Access Max() 子查询不起作用?

Posted

技术标签:

【中文标题】为啥我的 Access Max() 子查询不起作用?【英文标题】:Why is my Access Max() subquery not working?为什么我的 Access Max() 子查询不起作用? 【发布时间】:2020-04-25 03:11:54 【问题描述】:

我有一个 Microsoft Access 表,我想在其中返回一组记录,但仅限于最近的日期。

我的数据有 24 条记录,其中 12 条记录为 RECORD_DATE=#23/04/2020#,其他 12 条记录为 RECORD_DATE=#24/04/2020#(即 12 条记录在 4 月 23 日,12 条记录在 4 月 24 日);该字段设置为日期/时间。

我编写了一个子查询来获取每条记录的最大日期。

我遇到的问题是我的查询执行了,但返回了表中的所有记录(嗯,它正确应用了“WHERE Q.SITE_ID=?”),而不仅仅是那些具有 MAX(RECORD_DATE) 的记录。

这里是 SQL:

SELECT 
    Q.CONSUMABLE_RECORD_ID,
    Q.SITE_ID,
    Q.CONSUMABLE_STORAGE_ID,
    Q.CONSUMABLE_PRODUCT_ID,
    Q.CONSUMABLE_MEASUREMENT_UNIT_ID,
    Q.RECORD_DATE,
    Q.RECORD_VALUE,
    Q.LAST_DATE,
    Q.LAST_VALUE 
FROM 
    CONSUMABLE_RECORD AS Q 
WHERE 
    Q.SITE_ID =? 
AND 
    Q.RECORD_DATE=
    (
    SELECT 
        MAX(S.RECORD_DATE) 
    FROM 
        CONSUMABLE_RECORD AS S 
    WHERE 
        Q.CONSUMABLE_RECORD_ID=S.CONSUMABLE_RECORD_ID
    )

如果有任何区别,CONSUMABLE_RECORD_ID 是主键,我正在通过 C# 使用 OleDbCommand 执行查询,我使用的数据提供程序是 Microsoft.ACE.OLEDB.16.0。我也尝试在子查询中使用 MAX(CONSUMABLE_RECORD_ID),但这没有用 - 我更愿意将其保留为 Max(RECORD_DATE),因为理论上记录可以在日期上无序输入。

我需要做些什么才能使其正常工作?我在子查询中尝试了“TOP 1”,但仍然得到了 24 行。

我更愿意将其保留为子查询而不是内部联接等。

编辑: 这与This answer 不同。在那一个中​​,他们正在寻找一组中的前 3 个结果——我只想要最大记录。我尝试在问题的开头添加 TOP 1 和 ORDER BY(这需要 GROUP BY),但我仍然得到所有记录。

编辑 2: 样本数据:

想要的结果就是 RECORD_DATE=#24/4/20# 的所有记录。

【问题讨论】:

这能回答你的问题吗? Top n records per group sql in access 部分问题可能是参数中的国际日期结构。评论allenbrowne.com/ser-36.html 我该如何解决这个问题?我没有将数据作为参数传递(无论如何在其他代码中使用 OleDbParameter 都可以正常工作)。我尝试了 max(CONSUMABLE_RECORD_ID) 应该可以工作(如果可以,将确认这是一个日期格式问题),但这不起作用。表明子查询结构有一些基本的东西。 编辑问题以显示示例数据和所需结果。 【参考方案1】:

您似乎不想要相关子查询。这似乎是一种简洁的方式来编写您想要的内容:

SELECT cr.*
FROM Consumable_Record as cr
WHERE cr.Site_ID = ? AND
      cr.Record_Date = (SELECT MAX(cr2.Record_Date)
                        FROM Consumable_Record as cr2
                       );

注意有意义的表别名的使用。 QS 对您的数据没有任何意义。 CR 是表名的缩写。

如果当天网站没有任何记录,以上将不会返回记录。如果您想要 每个站点 的最新记录,请在相关子句中使用它:

SELECT cr.*
FROM Consumable_Record as cr
WHERE cr.Site_ID = ? AND
      cr.Record_Date = (SELECT MAX(cr2.Record_Date)
                        FROM Consumable_Record as cr2
                        WHERE cr2.Site_Id = cr.Site_Id
                       );

我怀疑这是你真正想要的。

【讨论】:

谢谢。我认为有意义的表别名是有意义的,但我为查询和子查询选择了 Q 和 S。我的代码实际上是动态的,类似于实体框架,所以我想要一个通用查询,我可以在其中调用方法,在其中传递表名和我想在 Max() 子查询中使用的字段。 所以对于子查询中的约束,我想我现在明白了为什么在我的示例中,加入主键意味着返回每条记录。这是否意味着它会尝试为主查询中的每条记录查找 Max(record_date),因此我只是将所有内容取回? @ainwood 。 . .基本上是的。您的相关性子句选择一条记录。日期与该记录匹配,因此最终选择了所有内容 - 一次比较。【参考方案2】:

正如@June7 所建议的,您可以在子查询中使用 TOP:

SELECT Q.Consumable_Record_ID, 
    Q.Site_ID, 
    Q.Consumable_Storage_ID, 
    Q.Consumable_Product_ID, 
    Q.Consumable_Measurement_Unit_ID, 
    Q.Record_Date, 
    Q.Record_Value, 
    Q.Last_Date, 
    Q.Last_Value
FROM Consumable_Record Q
WHERE Q.Site_ID=?
AND Q.Record_Date=(SELECT DISTINCT TOP 1 R.Record_Date FROM Consumable_Record R ORDER BY R.Record_Date DESC);

问候,

【讨论】:

当我第一次尝试这个时,我在查询中将Max() 更改为Distinct Top 1,但仍然得到了所有记录。然后,我直接尝试了您的 SQL,并且成功了。所以我看看还有什么不同。 AS S 与仅声明别名 S 没有区别,所以我删除了 WHERE Q.CONSUMABLE_RECORD_ID=S.CONSUMABLE_RECORD_ID,然后它起作用了。我在原来的 Max() 查询中删除了它,它也在那里正常工作。感谢您的指导 - 是否需要不需要子查询中的连接? 如果您考虑要求子查询返回什么,您是在要求它返回最近的日期 - 您实际上并不关心(至少在子查询部分中)关于其他任何事情。

以上是关于为啥我的 Access Max() 子查询不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

SQL / MS Access - 为啥这个 CASE 不起作用?

用于 MS Access 更新表的 OleDbDataAdapter,为啥我的更新不起作用?

为啥 webpack 代理不起作用(Access-Control-Allow-Origin 错误)?

Microsoft Access - 导航表单导致我的查询不起作用

为啥我的简单不匹配查询不起作用?

为啥我的媒体查询代码在 CSS 中不起作用?