Самая последняя запись в левом соединении - PullRequest
43 голосов
/ 07 апреля 2009

Представьте, что у меня есть следующие 3 таблицы в SqlServer:

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

У клиента может быть несколько адресов доставки и несколько продуктов.

То, что я хотел бы сделать, это перечислить количество клиентов для каждого штата, где штат определяется самой последней записью адреса. Например, «Сколько клиентов в последний раз получили продукт в каждом штате?». Поэтому я не заинтересован в каких-либо предыдущих адресных записях для Клиента, только в самых последних (определяется по AddressID).

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

Я бы обычно делал что-то вроде:

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

Однако, поскольку у Клиента может быть несколько Адресов, он будет учитываться только в состоянии самой последней записи адреса?

P.S. Выше приведен пример сценария, который легко объясняет соединения, которые я пытаюсь достичь, и не отражает фактический дизайн системы.

Ответы [ 3 ]

85 голосов
/ 07 апреля 2009

Попробуйте это:

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
2 голосов
/ 07 апреля 2009

Я не понимаю, как вы можете сделать это без таблиц Orders и OrderDetails. Таблица Orders будет содержать CustomerID ShippingDate и ShipToAddressID, а OrderDetails будет иметь OrderID и ProductID. Затем вам понадобится вложенный запрос, чтобы определить самый последний заказ (и, следовательно, самый последний адрес), присоедините его к деталям заказа, чтобы получить заказанные продукты, а затем отфильтруйте интересующий вас продукт.

1 голос
/ 07 апреля 2009

Вы также можете попробовать (при условии, что я правильно помню свой синтаксис SQLServer):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...