2013-02-14 5 views
5

Ich möchte Abfrage für die effektivsten Zeilen zu finden. Ich habe diese Tabellen:SQL-Abfrage, um die effektivsten Daten zu finden

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 

Und es sqlfiddle http://sqlfiddle.com/#!6/fe5b1/1/0

Meine Absicht finden optimale Verkäufer für Lager.

Wenn der Kunde 30A, 20A und 42B Produkte möchte. Ich muss zu "Mark" und "Peter" zurückkehren, weil Mark beide Produkte (30A und 20A) hat, also brauche Julia nicht.

Wie kann ich das in SQL lösen?

+1

Welche RDBMS verwenden Sie, MS SQL Server, MySQL, PostgreSQL ...? Ich denke MS SQL Server als SQL Fiddle benutzt es. Fügen Sie das benötigte Tag hinzu. Und den SQL Fiddle Link, den Sie hinzugefügt haben, bearbeiten Sie Ihre Frage besser und fügen Sie sie dort hinzu, damit andere Benutzer, die die Frage betrachten, nicht alle Kommentare durchgehen müssen, um sicherzustellen, dass sie alle Informationen haben – Yaroslav

+1

Ich denke, das Problem hier ist Ozan möchte die Mindestanzahl an Lieferanten finden, die eine Bestellung ausführen können. Wahrscheinlich möchten Sie die Liste der Lieferanten nach der Gesamtzahl der Artikel, die sie liefern können, bestellen. Die Codierung könnte jedoch schwierig sein. – bendataclear

+0

Ich denke, dass Ihr Problem komplexer als hier beschrieben ist. Was ist, wenn beide Verkäufer die gleiche Menge an Produkten haben (aber verschiedene Produkte?) –

Antwort

3

Verstanden mit Hilfe von temporären Tabellen

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 zu arbeiten: mit statischen Tabellen

Bitte testen:

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

gleiche gilt für tmpTable2. Dann ändern Sie obigen Code zu

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

Danke! Du bist der Mann ! – OzanWt

+0

Eine Frage, wie Abfrage funktioniert nicht in echten Daten. es gibt alle Produkte zurück, also kann Abfrage nicht löschen existiert von den verlockbaren in den realen Daten, unser productList Wert manchmal zu lang für Beispiel 1000 Zeichenlänge, also ist es Grund oder nicht für Ihre Meinung? – OzanWt

+0

Ich habe Probleme, das Problem zu verstehen. Erhalten Sie eine Fehlermeldung, die besagt, dass die temporäre Tabelle zu groß für eine temporäre Tabelle ist? Wenn ja, entfernen Sie die '#' vor dem Namen der temporären Tabelle und löschen Sie die Tabellen, wenn Sie sie nicht mehr benötigen. – fancyPants

-2

Ich denke, das könnte das sein, wonach Sie suchen?

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 

Ich hoffe, es hilft.

wenn Sie nur die oberen 2 Personen wünschen. Sie schreiben

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 

Ich denke, das ist das, was Sie suchen, da, wie ich es sehe, können Sie die zwei Personen auswählen möchten, die die höchste stockdata hat?

+2

Nein, das ist nicht, wonach er sucht. Er will Julia einfach nicht, weil Mark ihr Produkt und noch eins hat, deshalb ist Mark "effektiver". – fancyPants

+0

@tombom ja, du hast richtig gesagt. – OzanWt

+0

ah, hehe tut mir leid :) – Joe

Verwandte Themen