2013-02-14 4 views
5

最も効果的な行を見つけるためのクエリを書きたいと思います。私は、これらのテーブルがあります。最も効果的なデータを見つけるためのSQLクエリ

Sellers 
Id Name 
1 Mark 
2 Julia 
3 Peter 

Stocks 
Id SellerId ProductCode StockCount 
1  1   30A   10 
2  2   20A    4 
3  1   20A    2 
4  3   42B    3 

をそしてhttp://sqlfiddle.com/#!6/fe5b1/1/0

私のテントの在庫の最適な出品者を見つけることがsqlfiddle。

クライアントが30A、20A、および42B製品を必要とする場合。私はマークが両方の製品(30Aと20A)を持っているので、 "マーク"と "ピーター"に戻る必要があるので、そこには必要ありませんジュリア。

どのように私はこれをSQLで解決できますか?

+1

に変更します.Wich RDBMSは、MS SQL Server、MySQL、PostgreSQL ...を使用していますか?私はMSのSQL ServerはSQLのフィドルがそれを使用していると思います。必要なタグを追加します。そしてあなたが追加したSQL Fiddleのリンクは、あなたの質問をよりよく編集してそこに追加するので、質問を見ている他のユーザーは、すべてのコメントをすべて調べて、すべての情報を持っていることを確認する必要はありません – Yaroslav

+1

私は、注文を満たすことができる最低限の数のサプライヤーを探したい。あなたはおそらくサプライヤーのリストを供給可能なアイテムの総数で注文したいと思うでしょうが、コーディングは難しいかもしれません。 – bendataclear

+0

私はあなたの問題はここでより複雑になっていると思います。両方の売り手が同じ量の商品を持っている場合はどうなりますか(異なる商品ですか?) –

答えて

3

は、それが一時テーブルの助けを借り

SELECT 
    s.SellerId, 
    ProductList = STUFF((
         SELECT ',' + ProductCode FROM Stocks 
         WHERE s.SellerId = Stocks.SellerId 
         ORDER BY ProductCode FOR XML PATH('') 
         ) 
         , 1, 1, ''), COUNT(*) AS numberOfProducts 
INTO #tmptable 
FROM 
    Stocks s 
WHERE 
    s.ProductCode IN ('30A','20A','42B') 
    AND s.StockData > 0 
GROUP BY s.SellerId; 

/*this second temp table is necessary, so we can delete from one of them*/ 
SELECT * INTO #tmptable2 FROM #tmptable; 

DELETE t1 FROM #tmptable t1 
WHERE EXISTS (SELECT 1 FROM #tmptable2 t2 
       WHERE t1.SellerId != t2.SellerId 
       AND t2.ProductList LIKE '%' + t1.ProductList + '%' 
       AND t2.numberOfProducts > t1.numberOfProducts) 
; 

SELECT Name FROM #tmptable t INNER JOIN Sellers ON t.SellerId = Sellers.Id; 

UPDATEで動作するようになった:tmpTable2に同じ

CREATE TABLE tmptable (SellerId int, ProductList nvarchar(max), numberOfProducts int); 

静的テーブルと試しているしてください。上記のコードを

INSERT INTO tmpTable 
SELECT 
    s.SellerId, 
    ProductList = STUFF((
         SELECT ',' + ProductCode FROM Stocks 
         WHERE s.SellerId = Stocks.SellerId 
         ORDER BY ProductCode FOR XML PATH('') 
         ) 
         , 1, 1, ''), COUNT(*) AS numberOfProducts 
FROM 
    Stocks s 
WHERE 
    s.ProductCode IN ('30A','20A','42B') 
    AND s.StockData > 0 
GROUP BY s.SellerId; 

INSERT INTO tmpTable2 SELECT * FROM tmpTable; 

DELETE t1 FROM tmptable t1 
WHERE EXISTS (SELECT 1 FROM tmptable2 t2 
       WHERE t1.SellerId != t2.SellerId 
       AND t2.ProductList LIKE '%' + t1.ProductList + '%' 
       AND t2.numberOfProducts > t1.numberOfProducts) 
; 

SELECT * FROM tmpTable; 
DROP TABLE tmpTable, tmpTable2; 
+0

ありがとう!あなたは男です! – OzanWt

+0

クエリーのような1つの質問は、実際のデータに当てはまります。それはすべての製品を返すので、クエリの削除は実際のデータに魅力的なものから存在します。私たちのproductListの値は、例えば1000文字の長さでは長すぎます。 – OzanWt

+0

問題の理解に問題があります。一時テーブルが大きすぎて一時テーブルにならないなどのエラーが表示されますか? 「はい」の場合は、テンポラリテーブル名の前にある '#'を削除し、不要になったときにテーブルを削除します。 – fancyPants

-2

これはあなたが探しているかもしれないと思いますか?

Select name,sum(stockdata) as stockdata from sellers s1 join Stocks s2 on s1.id=s2.sellerid 
where ProductCode in ('30A','20A','42B') 
group by name 
order by sum(stockdata) desc 

私はそれが役に立ちそうです。

トップ2だけが必要な場合は、あなたは最高のstockdataを持っている二人を選択したい、私は、これはあなたが私はそれを参照してくださいどのようにするので、探しているものだと思います

Select top 2 name,sum(stockdata) as stockdata from sellers s1 join Stocks s2 on s1.id=s2.sellerid 
where ProductCode in ('30A','20A','42B') 
group by name 
order by sum(stockdata) desc 

書くのか?

+2

いいえ、これは彼が探しているものではありません。 Markは自分の製品にもう一つの製品を加えているので、Juliaが欲しくない。したがって、Markはもっと効果的だ。 – fancyPants

+0

@tombomはい、あなたは正しいと言いました。 – OzanWt

+0

ああ、heheそれについて申し訳ありません:) – Joe

関連する問題