查询一组记录最近更新的最佳方式

问题描述 投票:0回答:1

我不确定我的标题是否足够好地描述了我的问题。在这里。

我正在使用 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

我有什么想法可以让这项工作成功吗?

谢谢!

sql ms-access greatest-n-per-group
1个回答
0
投票

如果组具有唯一的别名,则可以在总计查询(分组依据)中使用计算字段。问题是你被困在一个通常不太好的别名中。但是,您通常将查询绑定到表单或报告,并且当时可以将别名重新设置为用户友好的内容。

'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: 以及表达式作为计算字段的类型。您获得组,然后根据组计算(查找)适当的值。

'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                  |
-----------------------------------------------------------------------------------------------

您必须决定如何处理平局和空值。一旦计算字段变得复杂,通常最好将其抽象为代码模块中的公共函数:

'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

注意:名称、值和日期是 Access 中的限制词,因此是 t_name、t_value、filing_date

© www.soinside.com 2019 - 2024. All rights reserved.