我不确定我的标题是否足够好地描述了我的问题。在这里。
我正在使用 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
我有什么想法可以让这项工作成功吗?
谢谢!
如果组具有唯一的别名,则可以在总计查询(分组依据)中使用计算字段。问题是你被困在一个通常不太好的别名中。但是,您通常将查询绑定到表单或报告,并且当时可以将别名重新设置为用户友好的内容。
'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