Jüngster Datensatz in einem linken Join

Stellen Sie sich vor, ich habe die folgenden 3 Tabellen in SqlServer:

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

Ein Kunde kann mehrere Lieferadressen und Mulitple-Produkte haben.

Was ich tun möchte, ist, die Anzahl der Kunden für jeden Staat aufzulisten, in dem der Staat durch den neuesten Adressdatensatz bestimmt wird. Wie z. B. "Wie viele Kunden haben zuletzt in jedem Staat ein Produkt erhalten?". Daher interessiere ich mich nicht für frühere Adressdatensätze für den Kunden, sondern nur für die aktuellsten (bestimmt durch AddressID).

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

Würde ich normalerweise so etwas tun wie:

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

Da ein Kunde jedoch mehrere Adressen haben kann, wird der Kunde nur im Status des letzten Adressdatensatzes gezählt?

P.S. Das obige ist ein reines Beispielszenario, um die Verknüpfungen, die ich zu erreichen versuche, leicht zu erklären und spiegelt keinen tatsächlichen Systementwurf wider.

Antwort auf "Jüngster Datensatz in einem linken Join " 3 von antworten

Sie könnten es auch versuchen (vorausgesetzt, ich erinnere mich richtig an meine SQLServer-Syntax):

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

Probieren Sie das aus:

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

Ich sehe nicht, wie Sie dies tun können, ohne Dassorden und OrderDetails Tabellen zu haben. Die Tabelle "Bestellungen" würde die CustomerID ShippingDate und ShipToAddressID enthalten, und OrderDetails hätte die OrderID und ProductID. Sie benötigen dann eine verschachtelte Abfrage, um die neueste Bestellung (und damit die neueste Adresse) zu bestimmen, diese mit den Bestelldetails zu verbinden, um die bestellten Produkte zu erhalten, und dann nach dem Produkt zu filtern, das Ihnen wichtig ist.