How to use SQL query to get earliest Date from multiple Tables?
Summary (Revised on 10 Jan 2016): I need info from 3 Tables (A, B, C), TableC has no primary key, hence I will get multiple [C_Date] record for each [B_ID].
' 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]
Below is one example of the data from TableC B_ID Name Value C_Date 73 Diamter 35.375 27-Jan-98 73 Diamter 35.376 27-Jan-98 73 Diamter 35.375 12-Apr-98 73 Diamter 35.374 19-Jul-98 73 Diamter 35.374 23-Sep-98 73 Diamter 35.374 30-Mar-99 73 Diamter 35.375 24-Oct-99 73 Diamter 35.374 24-Oct-99 73 Height 22.491 27-Jan-98 73 Height 21.908 12-Apr-98 73 Height 21.908 19-Jul-98 73 Height 21.915 23-Sep-98 73 Height 21.901 30-Mar-99 73 Height 21.909 24-Oct-99 73 Height 22.041 27-Jan-98
The Query Sequence is as follow:
1. Use where [A_Design] LIKE '%99%' to Get [A_ID] From TableA 2. Use 'Left Join' to link to TableB 3. Use 'Left Join' again to link to TableC
'Left Join' is just an example, it can be replaced by 'Inner Join'.
My current Sql query will return all the 15 rows for a B_ID (73), but I just need a single date - the earliest date (27-Jan-98), I am also not interested in other fields, such as [Name], [Value].
The following codes in VB.NET will retrieve multiple [C_Date]. If I only want the earliest [C_Date], how shall I modify my SQL script? Any suggestion and feedback would be greatly appreciated!
If you are not interested in VB.NET, please jump directly to Sql string, the question is for SQL syntax, which is independent from any specific programming language.
Many thanks to @PhilipXY and @Rory for the suggestion to test only within the Access environment, example codes and informative guides, finally my problem got solved.
Below SQL is a working copy from the MS Access SQL View of a Query.
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)));
With this revised SQL, now I am able to retrieve the following info from TableC:
B_ID C_Date 73 27-Jan-98
Problem solved! I would like to vote 5 for both @PhilipXY and @Rory. ( I assume that 5 is the highest point I can vote.)
VB.NET Codes:
================================================================ Imports System.Data.OleDb Imports System.Windows.Forms ' 1. Just add a DataGridView1 control on your winform, ' 2. then add a button (Named: 'btnTest') ' 3. Below is the button click handler, it will retrieve info from database and display it on the "DataGridView1" control.
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