2013-02-14 17 views
5

Voglio scrivere una query per trovare le righe più efficaci. Ho queste tabelle:Query SQL per trovare i dati più efficaci

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 

E ci sqlfiddle http://sqlfiddle.com/#!6/fe5b1/1/0

mio intento trovare Venditore ottimale per magazzino.

Se il cliente desidera prodotti 30A, 20A e 42B. Ho bisogno di tornare a "Mark" e "Peter" perché Mark ha entrambi i prodotti (30A e 20A), quindi non c'è bisogno di Julia.

Come posso risolvere questo in sql?

+1

Quale tipo di RDBMS stai usando, MS SQL Server, MySQL, PostgreSQL ...? Credo che MS SQL Server come SQL Fiddle lo sta usando. Aggiungi il tag necessario. E il collegamento SQL Fiddle che hai aggiunto, meglio modificare la tua domanda e aggiungerla lì, quindi gli altri utenti che guardano la domanda non devono passare attraverso tutti i commenti per essere sicuri di avere tutte le informazioni – Yaroslav

+1

Penso che il problema qui sia Ozan vuole trovare il numero minimo di fornitori in grado di soddisfare un ordine. Probabilmente vorrai ordinare l'elenco dei fornitori per il numero totale di articoli che possono fornire, tuttavia la codifica potrebbe essere complicata. – bendataclear

+0

Penso che il tuo problema sia più complesso di quanto descritto qui. Cosa succede se entrambi i venditori hanno la stessa quantità di prodotti (ma prodotti diversi?) –

risposta

3

preso a lavorare con l'aiuto di tabelle temporanee

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:

Si prega di avere una prova con tabelle statiche:

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

stesso per tmpTable2. Quindi cambia il codice sopra a

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

Grazie! Tu sei l'uomo ! – OzanWt

+0

Una domanda, come la query non funziona correttamente nei dati reali. restituisce tutti i prodotti, quindi la query non può essere eliminata da dati temporizzati nei dati reali, il nostro elenco dei prodotti a volte troppo lungo per esempio 1000 caratteri di lunghezza, quindi è un motivo o meno per la tua opinione? – OzanWt

+0

Ho problemi a capire il problema. Viene visualizzato un errore che dice che qualcosa come il tavolo temporaneo è troppo grande per essere un tavolo temporaneo? Se sì, rimuovere '#' davanti al nome della tabella temporanea e rilasciare le tabelle quando non ne hai più bisogno. – fancyPants

-2

Penso che questo potrebbe essere quello che stai cercando?

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 

Spero che sia d'aiuto.

se si desidera solo il 2 superiore ppl. Si scrive

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 

Penso che questo è quello che stai cercando, dal momento che come la vedo io, si desidera selezionare le due persone che ha il più alto stockdata?

+2

No, questo non è, quello che sta cercando. Semplicemente non vuole Julia perché Mark ha il suo prodotto più un altro, quindi Mark è più "efficace". – fancyPants

+0

@tombom si, hai detto bene. – OzanWt

+0

ah, hehe mi dispiace per quello :) – Joe

Problemi correlati