2009-04-07 11 views
36

Imagínese que tengo los siguientes 3 mesas en SqlServer:registro más reciente en una izquierda unirse a

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

Un cliente puede tener varias direcciones de entrega y productos Mulitple.

Lo que me gustaría hacer es enumerar el número de clientes para cada estado donde el estado se determina por el registro de dirección más reciente. Tales como "¿Cuántos clientes recibieron un producto por última vez en cada estado?". Por lo tanto, no estoy interesado en ningún registro de direcciones anterior para el cliente, solo el más reciente (determinado por AddressID).

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

Me normalmente hacer algo como:

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 

Sin embargo, como un cliente puede tener varias direcciones será el cliente sólo se contará en el Estado de la más reciente registro de dirección?

P.S. Lo anterior es puramente un escenario de ejemplo para explicar fácilmente las uniones que estoy tratando de lograr y no refleja un diseño de sistema real.

Respuesta

65

Prueba esto:

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

Justo lo que estaba buscando, muchas gracias. –

+0

¡Genial! ahora, ¿por qué no pensé en esto? –

+5

Esto estaba limpio. Felicitaciones a usted. –

0

También puede probar (suponiendo Recuerdo que mi sintaxis SQL Server correctamente):

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

no veo cómo se puede hacer esto sin tener órdenes y OrderDetails mesas. La tabla Pedidos incluiría el ID de envío del cliente y el Id. De dirección de envío, y los detalles de orden tendrían el ID de pedido y el ID de producto. Necesitará una consulta anidada para determinar el pedido más reciente (y por lo tanto la dirección más reciente), únase a los detalles del pedido para obtener los productos solicitados y luego filtre el producto que le interesa.

+1

Tiene razón, pero el escenario descrito es solo un ejemplo para tratar de explicar fácilmente lo que quiero lograr. He actualizado mi pregunta original con P.S. explicando esto. –

Cuestiones relacionadas