#sql #sql-server #tsql #left-join #sql-order-by
Вопрос:
Я пишу SQL — запрос, чтобы получить данные из более чем 3 таблиц, но для упрощения вопроса здесь я использую аналогичный сценарий с 3 таблицами.
Таблица 1 Заказчик (PK-Идентификатор клиента, имя)
Идентификатор клиента | Имя |
---|---|
1 | Джон |
2 | Тина |
3 | Сэм |
Таблица 2 Продажи (FK-Id, цена продажи)
ID | Цена продажи |
---|---|
1 | 200.00 |
2 | 300.00 |
3 | 400.00 |
Таблица 3 Заказ (PK-Id, FK-Идентификатор клиента, Дата, Сумма)
ID | Идентификатор клиента | Дата | Сумма |
---|---|---|---|
101 | 1 | 25-09-2021 | 30.0 |
102 | 1 | 27-09-2021 | 40.0 |
103 | 2 | 19-09-2021 | 60.0 |
В выходных данных Дата и сумма должны быть от самого последнего заказа (последняя дата) для клиента
Мой подход был
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount from
Customer as c
LEFT JOIN Sales s ON c.CustomerID = s.ID
LEFT JOIN (SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM Order o, Customer c1 WHERE c1.CustomerID = o.CustomerID ORDER BY o.Date DESC)
RecentOrder ON c.CustomerID = RecentOrder.CustomerID
Вывод, который я получаю
Идентификатор клиента, Имя, Место продажи, Дата, Сумма
Идентификатор клиента | Имя | Цена продажи | Дата | Сумма |
---|---|---|---|---|
1 | Джон | 200.00 | 27-09-2021 | 40.0 |
2 | Тина | 300.00 | нулевой | нулевой |
3 | Сэм | 400.00 | нулевой | нулевой |
Вывод, который я получаю, включает в себя самый последний заказ из всех заказов. Но я хочу получить последний заказ из заказов, сделанных этим клиентом
Требуемая Производительность
Идентификатор клиента, Имя, Место продажи, Дата, Сумма
Идентификатор клиента | Имя | Цена продажи | Дата | Сумма |
---|---|---|---|---|
1 | Джон | 200.00 | 27-09-2021 | 40.0 |
2 | Тина | 300.00 | 19-09-2021 | 60.0 |
3 | Сэм | 400.00 | нулевой | нулевой |
Комментарии:
1. Вероятно, пришло время избавиться от этого устаревшего синтаксиса 30-летней давности! Ваш запрос также должен привести к ошибке с таблицей с именем
order
— она должна быть[order]
— однако этого можно полностью избежать, вызвав ееorders
— предположительно, она содержит больше, чем один порядок?2. Некоторые люди предпочитают называть имена объектов «одноэлементными» именами, @Stu , поэтому проблема на самом деле в том, что это зарезервированное ключевое слово. Возможно
CustomerOrder
, это был бы лучший выбор, если бы ОП хотела получить имя синглтона.
Ответ №1:
Вместо подзапроса в левом соединении вы можете проверить с помощью внешнего приложения.
Проверьте следующим образом
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount
from Customer c
LEFT JOIN Sales s ON c.CustomerID = s.ID
OUTER APPLY (
SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM [Order] o
WHERE o.CustomerID = c.CustomerID ORDER BY o.Date DESC) RecentOrder`
Ответ №2:
Вам необходимо предварительно агрегировать или идентифицировать самый последний заказ для каждого заказа клиента, ваш запрос выбирает 1 строку для всех заказов.
Попробуйте следующее (непроверенное!)
select c.CustomerID, c.Name, s.SalePrice, o.Date, o.Amount
from Customer c
left join Sales s on c.CustomerID = s.ID
outer apply (
select top (1) date, amount
from [order] o
where o.CustomerId=c.CustomerId
order by Id desc
)o