【发布时间】:2016-04-13 22:21:30
【问题描述】:
如何使用 SQL 查询从多个表中获取最早的日期?
摘要(2016 年 1 月 10 日修订): 我需要来自 3 个表(A、B、C)的信息,TableC 没有主键,因此我将为每个 [B_ID] 获取多个 [C_Date] 记录。
' Description of Database:
' A Ms Access database file: "c:\DB\Data.mdb"
' It has 3 Tables: [TableA], [TableB], [TableC]
' TableA with Fields [A_ID], [A_Design]
' TableB with Fields [B_ID], [A_ID], [B_InventoryNum], [B_BlankNum]
' TableC with Fields [B_ID], [C_Name], [C_Value], [C_Date]
' TableA Primary Key is [A_ID]
' TableB Primary Key is [B_ID]
' TableC has no Primary Key, hence, for each [B_ID], there are multiple [C_Date]
以下是来自 TableC 的数据的一个示例
B_ID 名称 值 C_Date
73 直径 35.375 98 年 1 月 27 日
73 直径 35.376 98 年 1 月 27 日
73 直径 35.375 98 年 4 月 12 日
73 直径 35.374 98 年 7 月 19 日
73 直径 35.374 98 年 9 月 23 日
73 直径 35.374 99 年 3 月 30 日
73 直径 35.375 99 年 10 月 24 日
73 直径 35.374 99 年 10 月 24 日
73 身高 22.491 98 年 1 月 27 日
73 身高 21.908 98 年 4 月 12 日
73 身高 21.908 98 年 7 月 19 日
73 身高 21.915 98 年 9 月 23 日
73 身高 21.901 99 年 3 月 30 日
73 身高 21.909 99 年 10 月 24 日
73 身高 22.041 98 年 1 月 27 日
查询顺序如下:
1. 使用 where [A_Design] LIKE '%99%' 从 TableA 中获取 [A_ID] 2. 使用“左连接”链接到 TableB 3.再次使用'Left Join'链接到TableC'Left Join'只是一个例子,可以用'Inner Join'代替。
我当前的 Sql 查询将返回 B_ID (73) 的所有 15 行,但我只需要一个日期 - 最早的日期 (27-Jan-98),我对其他字段也不感兴趣,例如[名称],[值]。
VB.NET 中的以下代码将检索多个 [C_Date]。 如果我只想要最早的 [C_Date],我应该如何修改我的 SQL 脚本?任何建议和反馈将不胜感激!
如果你对VB.NET不感兴趣,请直接跳到Sql字符串,问题是SQL语法,它独立于任何特定的编程语言。
非常感谢@PhilipXY 和@Rory 提出的仅在Access 环境中进行测试的建议、示例代码和信息指南,终于解决了我的问题。
下面的 SQL 是来自查询的 MS Access SQL 视图的工作副本。
SELECT Distinct [TableA].[A_Design], [TableA].A_ID, [TableB].B_ID, [TableB].B_InventoryNum, [TableB].[B_BlankNum], [TableC].C_Date, [TableC].B_ID
FROM ([TableA] INNER JOIN [TableB] ON [TableA].A_ID = [TableB].B_ID) INNER JOIN [TableC] ON [TableB].B_ID = [TableC].B_ID
GROUP BY [TableA].[A_Design], [TableA].A_ID, [TableB].B_ID, [TableB].B_InventoryNum, [TableB].[B_BlankNum], [TableC].C_Date, [TableC].B_ID
HAVING ((([TableA].[A_Design]) Like '99') AND (([TableC].C_Date)=(SELECT TOP 1 Min([TableC].C_Date) FROM [TableC] Where [TableC].B_ID=[TableB].B_ID)));
使用这个修改后的 SQL,现在我可以从 TableC 中检索以下信息:
B_ID C_日期 73 98 年 1 月 27 日问题解决了!我想为@PhilipXY 和@Rory 投5 票。 (我假设 5 是我可以投票的最高点。)
VB.NET 代码:
======================================== ========================== 导入 System.Data.OleDb 导入 System.Windows.Forms ' 1. 只需在你的winform上添加一个DataGridView1控件, ' 2.然后添加一个按钮(命名:'btnTest') ' 3. 下面是按钮单击处理程序,它将从数据库中检索信息并将其显示在“DataGridView1”控件上。
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DB\Data.mdb;"
Dim cnn As OleDbConnection = New OleDbConnection(MDBConnString_)
cnn.Open()
Dim Sql As String
Sql = "SELECT " & "([A_Design]+Format([B_InventoryNum],""0000"")) AS DesignCodePK, [TableA].[A_ID], [A_Design], [TableB].[B_ID], [B_InventoryNum], [B_BlankNum], [C_Date] FROM ([TableA] LEFT JOIN [TableB] On [TableA].[A_ID] = [TableB].[A_ID]) " & " LEFT JOIN [TableC] On [TableB].[B_ID] = [TableC].[B_ID] Where [A_Design] LIKE '%99%' Order by [A_Design], [B_InventoryNum], [C_Date] "
Dim cmd As New OleDbCommand(Sql, cnn)
Dim DataAdapter As New OleDbDataAdapter(cmd)
Dim ds As System.Data.DataSet
ds = New System.Data.DataSet
DataAdapter = New OleDbDataAdapter(cmd)
DataAdapter.Fill(ds, "joined")
DataGridView1.DataSource = ds.Tables("joined")
cnn.Close()
End Sub
【问题讨论】:
-
如果问题是关于查询的,那么您应该简单地在问题中提出。您在寻找什么查询?
-
@philipxy TableC 共有 4 个字段([B_ID]、[C_Name]、[C_Value]、[C_Date])。通过 TableB 的左连接,我得到了 [B_ID]。通过使用[B_ID],我可以获得多个[C_Date],但我只需要最早的[C_Date],我尝试使用Min([C_Date]),没有任何运气。
-
@Shawn 我正在寻找只返回最早日期的查询([C_Date] 字段将返回多条记录)。详细信息请参考我的问题帖,谢谢您的回复。
-
@philipxy 更准确地说,我真的不知道如何在我的 Query 中使用 Min(),您能帮忙修改 Sql 字符串以添加到 Min() 中吗?谢谢。
-
您似乎只想为每个 B_ID 返回一行?即,如果您要 GROUP BY B_ID 那么对于具有给定 B_ID 的每一组行,您会想要一行 HAVING MIN C_DATE?