SQL WHERE NOT IN查询返回另一个表中的值

时间:2017-04-21 16:03:54

标签: sql vb.net ms-access

我正在尝试运行2个SELECT个查询。第一个查询选择所选客户和供应商匹配的Supplier_Product_Pricing中的所有数据。这将填写DataTable,并显示供应商,产品和价格。这个工作正常。

我正在尝试执行的下一个查询应该是从供应商与所选供应商匹配的Product Suppliers中选择所有产品,但未在Supplier_Product_Pricing中为所选客户分配价格。

基本上,我想从2个表中加载数据,这是一组记录,其中所选客户和供应商之间存在约定价格,然后与第二组数据相连,这是该供应商的剩余产品,没有商定的价格。

以下是我用来执行此操作的代码:

Try
   sql = "SELECT * FROM [Supplier_Product_Pricing] WHERE [Customer_Code] = @ccode AND " & _
         "[Supp_Code] = @scode ORDER BY [Product_Code]"
   cmd = New OleDb.OleDbCommand(sql, con)

    With cmd.Parameters
       .AddWithValue("@ccode", cust)
        .AddWithValue("@scode", cmbSuppCode.Text)
    End With

   Dim da As New OleDb.OleDbDataAdapter(cmd)
   Dim dt As New DataTable
   da.Fill(dt)

   Dim i As Integer = dt.Rows.Count

    Dim ds As New DataSet
        Using da2 As New OleDbDataAdapter("SELECT * FROM [Product Suppliers] WHERE " & _
                                         "[Supplier_Code] = ? AND [Product_Code] NOT IN " & _
                                        "(SELECT [Product_Code] FROM " & _
                                        "[Supplier_Product_Pricing] WHERE [Customer_Code] = ? " & _
                                        "AND [Supp_Code] = ?) ORDER BY [Product_Code]", con)
            With da2.SelectCommand.Parameters
                .Add("@scode", OleDbType.VarChar).Value = cmbSuppCode.Text
                .Add("@ccode", OleDbType.VarChar).Value = cust
                .Add("@supp", OleDbType.VarChar).Value = cmbSuppCode.Text
            End With

            da2.Fill(ds)
        End Using

  For Each dr As DataRow In ds.Tables(0).Rows
     dt.Rows.Add(dr.Item("Supplier_Code"), dr.Item("Product_Code"), Nothing)
  Next

但结果是,它显示所有记录,其价格在顶部达成一致,然后再次显示所有供应商的产品,无论是否有价格。见下文。

enter image description here

正如您所看到的那样,产品价格的4行将在下面重复,但没有价格。

为什么查询返回两个表中的行,尽管使用了NOT IN子句?

修改

帮助获得赏金 - 当使用一个参数时,如第一个答案所示,根本不会返回任何结果。

当使用2个不同的参数时,正如我最初所做的那样,它会返回与图像中显示的相同的结果,无论我是否使用DISTINCT

表[Product Suppliers] - 存储已向供应商提供的所有产品。因此,在给出的示例中,与'JON_B'关联的所有产品都将在此处以'JON_B'作为供应商。所有JON_B的产品如下图所示。

enter image description here enter image description here

表[Supplier_Product_Pricing]

enter image description here

如您所见,只有8种产品与JON_B相关联。当向其中的4个添加价格时,它会以价格返回4,并且再次没有价格。我只需要显示价格为Supplier_Product_Pricing的价格,加上Product Suppliers

中没有价格的价格

编辑2

继续@Bugs提供的答案

Dim sqlString As String = "   SELECT [Product Suppliers].[Supplier_Code], " & _
                        "          [Product Suppliers].[Product_Code], " & _
                        "          [Supplier_Product_Pricing].[Product_Price] " & _
                        "     FROM [Product Suppliers] LEFT OUTER JOIN " & _
                        "          [Supplier_Product_Pricing] ON [Product Suppliers].[Product_Code]=[Supplier_Product_Pricing].[Product_Code] AND " & _
                        "                                        [Product Suppliers].[Supplier_Code]=[Supplier_Product_Pricing].[Supp_Code] " & _
                        "   WHERE [Product Suppliers].[Supplier_Code] = ? " & _
                        "     AND [Supplier_Product_Pricing].[Customer_Code] = ? " & _
                        "ORDER BY [Product Suppliers].[Product_Code]"

        Dim dt As New DataTable
        Dim cmd As New OleDbCommand(sqlString, con)

            With cmd.Parameters
                .Add(New OleDbParameter("@scode", OleDbType.VarChar)).Value = cmbSuppCode.Text
                .Add(New OleDbParameter("@ccode", OleDbType.VarChar)).Value = cust
            End With

            dt.Load(cmd.ExecuteReader())

        ugPricing.DisplayLayout.Bands(0).Override.AllowAddNew = Infragistics.Win.UltraWinGrid.AllowAddNew.No
        ugPricing.DataSource = dt

        Try
            ugPricing.DisplayLayout.Bands(0).Columns("Customer_Code").Hidden = True
        Catch
        End Try

这一次,它只是显示价格的物品,而不是没有价格的物品。 enter image description here

相关表格中的数据:

[Product Suppliers]

enter image description here

[Supplier_Product_Pricing]

enter image description here

2 个答案:

答案 0 :(得分:1)

我相信你所追求的目标可以在一个查询中完成,而不是使用两个,然后向dt添加行。我已经将查询弹出到一个变量中,试着让它在这个答案中更容易阅读。

我也直接加载到DataTable。这只是我的偏好。

用这个替换两个查询代码:

Dim sqlString As String = "   SELECT [Product Suppliers].[Supplier_Code], " & _
                          "          [Product Suppliers].[Product_Code], " & _
                          "          [Supplier_Product_Pricing].[Product_Price] " & _
                          "     FROM [Product Suppliers] LEFT OUTER JOIN " & _
                          "          [Supplier_Product_Pricing] ON ([Product Suppliers].[Product_Code]=[Supplier_Product_Pricing].[Product_Code] AND " & _
                          "                                         [Product Suppliers].[Supplier_Code]=[Supplier_Product_Pricing].[Supp_Code] AND " & _
                          "                                         [Supplier_Product_Pricing].[Customer_Code] = ?) " & _
                          "   WHERE [Product Suppliers].[Supplier_Code] = ? " & _
                          "ORDER BY [Product Suppliers].[Product_Code]"

Dim dt As New DataTable
Using cn As OleDbConnection = con,
      cmd As New OleDbCommand(sqlString, cn)

    cn.Open()

    With cmd.Parameters
        .Add(New OleDbParameter("@ccode", OleDbType.VarChar)).Value = cust
        .Add(New OleDbParameter("@scode", OleDbType.VarChar)).Value = cmbSuppCode.Text
    End With

    dt.Load(cmd.ExecuteReader())
End Using

这是我的数据的屏幕截图:

enter image description here

试一试,看看它为你做了什么。

我已在上复制了此内容,因为我没有,但相同的查询应该有效。

答案 1 :(得分:0)

它有两个变化。我注意到你为同一个供应商使用不同的参数名称,我认为没有必要,我使用了supplier_product_pricing表中的product_code。

Select * from productSuppliers 
 where supplier_code = @sCode  
   and product_code NOT in  
    (select distinct product_code from supplier_product_pricing 
     where customer_code = @cust 
     and supp_code = @sCode) 
  Order by Product_code