2017-04-21 8 views
2

2つのクエリを実行しようとしています。SELECT最初のクエリは、選択した顧客とサプライヤが一致するすべてのデータをSupplier_Product_Pricingから選択します。これにより、DataTableが入力され、サプライヤ、製品、価格が表示されます。これはうまく動作します。他のテーブルにある値を返すSQL WHERE NOT INクエリ

私が実行しようとしている次のクエリは、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句を使用していても、両方のテーブルにある行がクエリで返されるのはなぜですか?

EDIT

恵みを支援するために - つのパラメータを使用する場合は、最初の答えで提案されているように、何も結果がまったく返されません。

2つの異なるパラメータを使用する場合、私が最初に行ったように、DISTINCTを使用するかどうかにかかわらず、画像に示されているのと同じ結果が返されます。

表[Product Suppliers] - サプライヤーに与えられたすべての製品を保管しています。したがって、与えられた例では、 'JON_B'に関連付けられたすべての製品がサプライヤとして 'JON_B'とここにあります。 JON_Bの製品はすべて下の画像にあります。

enter image description hereenter image description here

表[Supplier_Product_Pricing]

enter image description here

あなたが見ることができるように、JON_Bにリンクされている唯一の8製品があります。そのうちの4つに価格を追加すると、4つの価格だけでなく、価格のないものもすべて返されます。私はSupplier_Product_Pricingからの価格でものを表示する必要があり、プラスProduct Suppliers

EDIT 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

答えて

1

私は1つのクエリではなく、2を使用して、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

はい!それは終わった、ありがとう。私はいくつかの微調整をする必要がありますが、これで私はそれが必要なものを表示します。これにこだわってくれてありがとう。 – David

+0

@David、問題ではなく、私たちがそれを並べ替えることができてうれしいです。 – Bugs

0

その中の2つの変更があります。私はあなたが同じサプライヤのために異なるパラメータ名を使用していることに気づいた、私はそれが必要ではないと思うし、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 
+0

まず、MS-Accessであるため、サプライヤに異なるパラメータを使用する必要があります。これは 'DISTINCT'部分でさえも、まったく違いはありません。 – David

関連する問題