如何使用SQL查询从多个表中获取最早的日期?

时间:2016-01-09 06:36:41

标签: sql vb.net ms-access

如何使用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]

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

查询序列如下:

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

'左加入'只是一个例子,它可以被内部加入'替换。

我当前的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_Date
73    27-Jan-98

问题解决了!我想为@PhilipXY和@Rory投票5。 (我假设5是我可以投票的最高点。)

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

1 个答案:

答案 0 :(得分:2)

获取B_ID使用的最短日期

select min(c_date) from TableC where b_id = XXXX

获取所有分钟日期

select b_id, min(c_date) as MinDate
from TableC group by b_id

然后,您可以将该查询加入其他表:

select *
from TableB
left join (
    select b_id, min(c_date) as MinDate
    from TableC group by b_id
) as minimumDates
    on minimumDates.b_id = TableB.b_id

如果您遇到查询语法问题,请尝试直接针对MS Access运行SQL,而不是通过VB运行。这样可以更容易地检查什么/不起作用。如果你无法让GROUP BY工作,那么尽可能简单地开始一个新的查询,就像我上面的第一个select一样。忘记您真正想要的列,只需查看一个简单的查询,然后一次添加JOINWHERE和一列。