提问人:Dave M 提问时间:11/18/2023 最后编辑:June7Dave M 更新时间:11/19/2023 访问量:36
查询一组记录的最新更新的最佳方式
Best way to query most recent update to a group of records
问:
我不确定我的标题是否足够好地描述了我的问题。在这里。
我正在使用 MS Access,我的 SQL 技能非常基础。我有一个有很多行的数据库。唯一 ID 是一个数字。对于每一行,都有一个单独的“文件编号”值,该值在行之间可能相同。假设这是因为公司更新了会计记录,并将新记录(具有美元价值)分配给相同的“文件编号”。
具有相同文件编号的记录之间的不同之处在于它们的创建日期。因此,我想返回一个表,该表仅显示每个文件编号的一行,其中该行是文件的最新更新。我认为这可能需要使用 MAX(filing_date)。
但是我的SQL不起作用。在 Stack Overflow 上看到一些关于类似内容的帖子后,我写道:
SELECT table.unique_id, table.name, table.file_number, Max(table.filing_date) AS last_date, table.value
FROM table INNER JOIN table AS filings ON table.file_number = filings.file_number
WHERE table.form_type="update"
GROUP BY table.unique_id, table.name, table.file_number, table.value
我的 SQL 不会删除我要删除的行,即文件编号较早更新的行。
我能够使用更简单的查询(没有自联接的查询)删除较旧的条目,但前提是我没有包含unique_id或值。那个 SELECT 语句只是:
SELECT name, file_number, Max(filing_date) AS last_date
我有什么想法可以做到这一点吗?
谢谢!
答:
0赞
mazoula
11/19/2023
#1
如果组具有唯一别名,则可以在查询总数(分组依据)中使用计算字段。问题是你被一个通常不太好的别名卡住了。但是,通常将查询绑定到窗体或报表,并且可以将别名重新设置为当时用户友好的内容。
'TableB
----------------------------------------------------------------------------------------------------------
| ID | file_number | t_name | t_value | filing_date |
----------------------------------------------------------------------------------------------------------
| 1 | 1 | name1 | $5.00 | 11/1/2023 |
----------------------------------------------------------------------------------------------------------
| 2 | 1 | name2 | $6.00 | 11/2/2023 |
----------------------------------------------------------------------------------------------------------
| 3 | 2 | name3 | $15.00 | 11/3/2023 |
----------------------------------------------------------------------------------------------------------
| 4 | 2 | name3 | $16.00 | 11/4/2023 |
----------------------------------------------------------------------------------------------------------
| 5 | 3 | name4 | $4.00 | 11/5/2023 |
----------------------------------------------------------------------------------------------------------
关键是在此处使用唯一别名 D: 和 F: 以及 expression 作为计算字段的类型。您获取组,然后根据组计算(查找)适当的值。
'note the date delimeters # #
t_name: DLookUp("t_name","TableB","(file_number = " & [F] & ") AND ( filing_date = #" & [D] & "#)")
t_value: DLookUp("t_value","TableB","(file_number = " & [F] & ") AND ( filing_date = #" & [D] & "#)")
'sql pane:
SELECT TableB.file_number AS F, Max(TableB.filing_date) AS D, DLookUp("t_name","TableB","(file_number = " & [F] & ") AND ( filing_date = #" & [D] & "#)") AS t_name, DLookUp("t_value","TableB","(file_number = " & [F] & ") AND ( filing_date = #" & [D] & "#)") AS t_value
FROM TableB
GROUP BY TableB.file_number
ORDER BY TableB.file_number;
'results:
-----------------------------------------------------------------------------------------------
| F | D | t_name | t_value |
-----------------------------------------------------------------------------------------------
| 1 | 11/2/2023 | name2 | 6 |
-----------------------------------------------------------------------------------------------
| 2 | 11/4/2023 | name3 | 16 |
-----------------------------------------------------------------------------------------------
| 3 | 11/5/2023 | name4 | 4 |
-----------------------------------------------------------------------------------------------
您必须决定如何处理 tie 和 null。一旦计算字段变得复杂,通常最好将其抽象为代码模块中的公共函数:
'break tie with ID, replace dlookup in query with GetName(F,D)
Public Function GetName(F As Long, D As Date) As String
Dim ID As Long
ID = DMax("ID", "TableB", "(file_number = " & F & ") AND ( filing_date = #" & D & "#)")
GetName = DLookup("t_name", "TableB", "ID = " & ID)
End Function
Public Function GetValue(F As Long, D As Date) As String
Dim ID As Long
ID = DMax("ID", "TableB", "(file_number = " & F & ") AND ( filing_date = #" & D & "#)")
Debug.Print ID
GetValue = DLookup("t_value", "TableB", "ID = " & ID)
End Function
注意:name、value 和 Date 是 Access 中的受限制词,因此t_name、t_value filing_date
评论