【问题标题】:SQL WHERE NOT IN query returning values that are in the other tableSQL WHERE NOT IN 查询返回另一个表中的值
【发布时间】:2017-04-21 16:03:53
【问题描述】:

我正在尝试运行 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

但是这样做的结果是,它会在顶部显示所有约定价格的记录,然后在其下再次显示所有供应商的产品,无论是否有约定的价格。见下文。

如您所见,带有产品价格的 4 行随后在下方重复,但没有价格。

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

编辑

帮助赏金 - 使用一个参数时,如第一个答案中所建议的那样,根本不会返回任何结果。

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

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

表 [Supplier_Product_Pricing]

如您所见,只有 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

这一次它只显示有价格的商品,而不是没有价格的商品。

相关表格中的数据:

[Product Suppliers]

[Supplier_Product_Pricing]

【问题讨论】:

    标签: sql vb.net ms-access


    【解决方案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
    

    这是我的数据截图:

    试一试,看看它对你有什么作用。

    我已经在 上复制了这个,因为我没有 ,但同样的查询应该可以工作。

    【讨论】:

    • 是的!已经搞定了,谢谢。我需要进行一些调整,但这确实显示了我需要的内容。感谢您坚持这一点。
    • @David,没问题,很高兴我们能对其进行排序。
    【解决方案2】:

    它有两个变化。我注意到您对同一供应商使用不同的参数名称,我认为这不是必需的,我对来自供应商产品定价表的产品代码使用了不同的名称。

    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
    

    【讨论】:

    • 首先,它必须为供应商使用不同的参数,因为它是MS-Access。即使使用DISTINCT 部分,这仍然没有任何区别。
    猜你喜欢
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 2022-01-21
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多