2009-04-07 12 views
36

Immaginate Ho le seguenti 3 tavoli in SqlServer:più recenti record in una sinistra unirsi

Customer (CustomerID, FirstName, LastName) 
Address (AddressID, CustomerID, Line1, City, State) 
Product (ProductID, CustomerID, Description) 

Un cliente può avere più indirizzi di consegna e prodotti mulitple.

Quello che mi piacerebbe fare è elencare il numero di clienti per ogni Stato in cui lo Stato è determinato dal record di indirizzo più recente. Ad esempio: "Quanti clienti hanno ricevuto in ultimo un prodotto in ciascuno Stato?". Pertanto non sono interessato a nessun record di indirizzo precedente per il cliente, solo il più recente (determinato da AddressID).

State | Number of Customers 
-------------------------- 
CA | 32 
GA | 12 
TX | 0 
OH | 18 

io normalmente fare qualcosa di simile:

SELECT a.State, count(c.CustomerID) 
FROM Product p 
INNER JOIN Customer c ON c.CustomerID = p.CustomerID 
LEFT JOIN Address a ON a.CustomerID = c.CustomerID 
WHERE p.ProductID = 101 
GROUP BY a.State 

Tuttavia, come un cliente può avere più indirizzi sarà il cliente viene conteggiato solo nello Stato della più recente record di indirizzo?

P.S. Quanto sopra è puramente uno scenario di esempio per spiegare facilmente i join che sto cercando di raggiungere e che non riflette un design di sistema reale.

risposta

65

Prova questo:

SELECT a.State, count(c.CustomerID) 
FROM Product p 
INNER JOIN Customer c ON c.CustomerID = p.CustomerID 
LEFT JOIN Address a ON a.CustomerID = c.CustomerID 
     AND a.AddressID = 
     (
      SELECT MAX(AddressID) 
      FROM Address z 
      WHERE z.CustomerID = a.CustomerID 
     ) 
WHERE p.ProductID = 101 
GROUP BY a.State 
+0

Proprio quello che stavo cercando, molte grazie. –

+0

Ottimo! ora, perché non ci ho pensato! –

+5

Questo era pulito. Complimenti a te. –

0

Si potrebbe anche provare (supponendo che mi ricordo la mia sintassi SQLServer correttamente):

SELECT state, count(customer_id) 
FROM (
    SELECT 
     p.customer_id 
     , (SELECT TOP 1 State FROM Address WHERE Address.CustomerID = p.CustomerID ORDER BY Address.ID DESC) state 
    FROM Product p 
    WHERE p.ProductID = 101) 
GROUP BY state 
1

Non vedo come si può fare questo senza dover Ordini e OrderDetails tabelle. La tabella Ordini includerebbe CustomerID ShippingDate e ShipToAddressID e OrderDetails avrebbe OrderID e ProductID. Avrai quindi bisogno di una query nidificata per determinare l'ordine più recente (e quindi l'indirizzo più recente), aggiungerlo ai dettagli dell'ordine per ottenere i prodotti ordinati, quindi filtrare il prodotto che ti interessa.

+1

Sei corretto ma lo scenario descritto è puramente un esempio per cercare di spiegare facilmente cosa voglio raggiungere. Ho aggiornato la mia domanda originale con un P.S. spiegando questo. –

Problemi correlati