SELECT WHERE NOT IS / EXISTS Subquery(VB.NET,Access)的麻烦

时间:2014-11-21 02:50:51

标签: sql vb.net subquery

在我遇到的问题上需要一些帮助。 这是代码:

Private Sub dtpStartDate_ValueChanged(sender As Object, e As EventArgs) Handles dtpStartDate.ValueChanged
    startDateChanged = 1

    If endDateChanged = 1 Then
        cbLocation.Enabled = True
        cbLocation.Items.Clear()
        cbLocation.Items.Add(New ListViewItem(""))
        Dim unbookedLocationsSQL As String = "SELECT locationID FROM Locations WHERE NOT EXISTS (Select LocationID FROM Bookings WHERE @startDate <= bookingEndDate AND bookingStartDate <= @endDate)"
        Dim unbookedLocationsCommand = New OleDbCommand(unbookedLocationsSQL, globalVariables.objConnection)
        Dim unbookedLocationsAdapter As New OleDbDataAdapter(unbookedLocationsSQL, globalVariables.objConnection)
        Dim unbookedLocationsDataSet As New DataSet

        unbookedLocationsCommand.Parameters.AddWithValue("startDate", dtpStartDate.Value)
        unbookedLocationsCommand.Parameters.AddWithValue("endDate", dtpEndDate.Value)

        unbookedLocationsAdapter.Fill(unbookedLocationsDataSet, "Locations")

        With cbLocation
            .DataSource = unbookedLocationsDataSet.Tables("Locations")
            .DisplayMember = "locationID"
            .ValueMember = "locationID"
        End With
    End If
End Sub

首先,如果您将sql语句更改为“SELECT * from locations”,则组合框只显示所有位置。

我想要实现的是这个;当有人更改两个日期时间选择器时,组合框将启用并填充在这两个日期之间未预订的位置列表,这将由预订表确定。 我知道SQL语句是错误的。我已经尝试了各种各样的组合,并试图隔离一些碎片,但我无法得到任何子查询来做我想做的事。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:0)

我认为这里出了问题

WHERE @startDate <= bookingEndDate AND bookingStartDate <= @endDate

尝试将其更改为

WHERE bookingStartDate >= @startDate AND bookingEndDate <= @endDate

还要记住将“.Date”放在参数中..

unbookedLocationsCommand.Parameters.AddWithValue("startDate", dtpStartDate.Value.Date)

答案 1 :(得分:0)

如果我理解正确,Bookings表的每个条目都会反映一个预订,即使是某个位置。在这种情况下,您需要:

WHERE @startDate >= bookingEndDate OR bookingStartDate >= @endDate

而不是

WHERE @startDate <= bookingEndDate AND bookingStartDate <= @endDate

此外,如果Bookings表可以为同一位置设置多个条目,则不起作用:您必须确保该位置的预订没有与输入日期重叠。

由于我无法对其他答案发表评论,我将在此处注意Codemunkeee的答案是错误的 - 使用他的查询(WHERE bookingStartDate >= @startDate AND bookingEndDate <= @endDate),您将获得预订与请求日期重叠的那些位置,所以它与你想要的相反。当然,除非我误解了Bookings表格。

答案 2 :(得分:0)

以下是现在正在运行的代码:

 Private Sub dtpStartDate_ValueChanged(sender As Object, e As EventArgs) Handles dtpStartDate.ValueChanged
        startDateChanged = 1

        If endDateChanged = 1 Then
            cbLocation.Enabled = True
            Me.Refresh()
            cbLocation.Items.Add(New ListViewItem(""))
            Dim unbookedLocationsSQL As String = "SELECT * FROM Locations WHERE LocationID NOT IN (SELECT LocationID FROM Bookings WHERE bookingEndDate >= @startDate AND bookingStartDate <= @endDate)"
            Dim unbookedLocationsCommand = New OleDbCommand(unbookedLocationsSQL, globalVariables.objConnection)
            Dim unbookedLocationsAdapter As New OleDbDataAdapter(unbookedLocationsSQL, globalVariables.objConnection)
            Dim unbookedLocationsDataSet As New DataSet

            unbookedLocationsCommand.Parameters.AddWithValue("startDate", dtpStartDate.Value)
            unbookedLocationsCommand.Parameters.AddWithValue("endDate", dtpEndDate.Value)
            unbookedLocationsAdapter.SelectCommand = unbookedLocationsCommand
            unbookedLocationsAdapter.Fill(unbookedLocationsDataSet, "Locations")

            With cbLocation
                .DataSource = unbookedLocationsDataSet.Tables("Locations")
                .DisplayMember = "LocationName"
                .ValueMember = "LocationID"
            End With
        End If
    End Sub