为啥我的 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
);
注意有意义的表别名的使用。 Q
和 S
对您的数据没有任何意义。 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 错误)?