2010-09-09 27 views
5

Sto cercando di avvolgere la mia testa in questa mattina.SQL enigma, come selezionare la data più recente per la parte, ma solo 1 riga per parte (unica)

Sto cercando di mostrare lo stato inventory per le parti (per i nostri prodotti) e questa query diventa complessa solo se provo a restituire tutte le parti.

Permettetemi di porre fuori:

  • singola tabella inventoryReport
  • Ho una lista distinta di parti X desidero visualizzare, il cui risultato deve essere X # di righe (1 riga per parte mostrando l'ultima voce di inventario).
  • tabella è costituita da voci datate di modifiche di inventario (quindi ho solo bisogno della voce data LATEST per parte).
  • tutti i dati contenuti in questa tabella singola, quindi nessun join necessario.

Attualmente per 1 singola parte, è abbastanza semplice e posso fare questo nel modo seguente SQL (per darvi un'idea):

SELECT  TOP (1) ldDate, ptProdLine, inPart, inSite, inAbc, ptUm, inQtyOh + inQtyNonet AS in_qty_oh, inQtyAvail, inQtyNonet, ldCustConsignQty, inSuppConsignQty 
FROM   inventoryReport 
WHERE  (ldPart = 'ABC123') 
ORDER BY ldDate DESC 

che mi ottiene il mio TOP 1 fila, in modo da semplice per parte, tuttavia ho bisogno di mostrare tutto X (diciamo 30 parti). Quindi ho bisogno di 30 righe, con quel risultato. Ovviamente la soluzione semplice sarebbe quella di eseguire il loop X # di chiamate sql nel mio codice (ma sarebbe costoso) e sarebbe sufficiente, ma per questo scopo mi piacerebbe lavorare ancora questo SQL per ridurre le chiamate x # al db (se non necessario) fino a una sola query.

Da quello che posso vedere qui ho bisogno di tenere traccia dell'ultima data per articolo in qualche modo mentre cerco il mio set di risultati.

Vorrei infine fare un

WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc) 

per limitare le parti di cui ho bisogno. Spero di aver chiarito abbastanza bene la mia domanda. Fammi sapere se hai un'idea. Non riesco a fare un DISTINCT poiché le righe non sono le stesse, la data deve essere la più recente e ho bisogno di un massimo di X righe.

Pensieri? Sono bloccato ...

risposta

2

EDIT: Assicurarsi di testare le prestazioni di ciascuna soluzione. Come indicato in this question, il metodo CTE può sovraperformare utilizzando ROW_NUMBER.

;with cteMaxDate as (
    select ldPart, max(ldDate) as MaxDate 
     from inventoryReport 
     group by ldPart 
) 
SELECT md.MaxDate, ir.ptProdLine, ir.inPart, ir.inSite, ir.inAbc, ir.ptUm, ir.inQtyOh + ir.inQtyNonet AS in_qty_oh, ir.inQtyAvail, ir.inQtyNonet, ir.ldCustConsignQty, ir.inSuppConsignQty 
    FROM cteMaxDate md 
     INNER JOIN inventoryReport ir 
      on md.ldPart = ir.ldPart 
       and md.MaxDate = ir.ldDate 
5
SELECT * 
    FROM (SELECT i.*, 
     ROW_NUMBER() OVER(PARTITION BY ldPart ORDER BY ldDate DESC) r 
     FROM inventoryReport i 
     WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc) 
     ) 
    WHERE r = 1 
2

Devi iscriverti in un sub-query:

SELECT i.ldPart, x.LastDate, i.inAbc 
FROM inventoryReport i 
INNER JOIN (Select ldPart, Max(ldDate) As LastDate FROM inventoryReport GROUP BY ldPart) x 
on i.ldPart = x.ldPart and i.ldDate = x.LastDate 
Problemi correlati