#sql #oracle #plsql
#sql #Oracle #plsql
Вопрос:
У меня есть две очень простые таблицы в Oracle 9G:
Клиент
userid | firstName | lastName | email
------- ----------- ---------- ---------------------
1 user1 User1 user1@mail.in
2 user2 User2 user2@mail.in
Порядок
orderiD | userId | OrderType | Order_Date | Amount
-------- -------- ----------- ------------ -------
1 1 0 12/12/2009 1
2 1 1 13/12/2009 2
3 1 1 14/12/2009 3
4 2 0 12/12/2009 4
5 2 1 16/12/2009 2
6 1 0 14/12/2009 5
7 2 1 17/12/2009 4
8 2 0 10/12/2010 2
Я хочу выбрать всех пользователей, у которых есть заказы типа 0
select *
from Customer c
inner join Order o on c.userid = o.userid
where o.orderType = '0'
Результатом является:
orderiD | userId | OrderType | Order_Date | Amount
-------- -------- ----------- ------------ --------
1 1 0 12/12/2009 1
4 2 0 12/12/2009 4
6 1 0 14/12/2009 5
8 2 0 10/12/2010 2
Теперь мне нужно изменить этот запрос, чтобы указать только дату последней покупки для каждого идентификатора пользователя и получить результат, подобный этому:
orderiD | userId | OrderType | Order_Date | Amount
-------- -------- ----------- ------------ --------
6 1 0 14/12/2009 5
8 2 0 10/12/2010 2
Как я должен изменить свой запрос, чтобы получить этот результат?
Ответ №1:
SELECT *
FROM order o
WHERE o.orderType ='0'
AND o.order_date =
( SELECT MAX(o2.order_date)
FROM order o2
WHERE o2.userid = o.userid
AND o2.orderType = '0'
)
или
SELECT o.*
FROM order o
JOIN
( SELECT userid
, MAX(order_date) AS lastPurchaseDate
FROM order
WHERE o.orderType ='0'
GROUP BY userid
) AS grp
ON grp.userid = o.userid
AND grp.lastPurchaseDate = o.order_date
Ответ №2:
Попробуйте это:
select *
from customer c
, order o
where c.userid = o.userid
and o.orderType ='0'
and o.order_date = (
select max(o2.order_date)
from order o2
where o2.userid = o.userid
)
Ответ №3:
Не требуется подзапрос, только агрегированные функции.
select c.userId, o.OrderType,
max(o.Order_Date),
max(o.orderiD) keep (dense_rank last order by order_date),
max(o.Amount) keep (dense_rank last order by order_date)
from Customer c inner join Order o
on c.userid = o.userid where o.orderType ='0'
group by c.userId, o.OrderType
Ответ №4:
SELECT *
FROM Order o
INNER JOIN
(SELECT MAX(o.id) AS maxid
FROM Customer c
INNER JOIN Order o ON c.userid = o.userid
WHERE o.orderType ='0'
GROUP BY c.userid) x ON x.maxid = o.id
Комментарии:
1. Как это позволяет получить максимальную дату?
2. В некотором смысле решение является обманом / сокращением, поскольку оно предполагает, что o.id будут упорядочены по дате (что, вероятно, соответствует действительности). Но вы могли бы представить сценарий, в котором изменяется order_date, и в этом случае этот SQL был бы не совсем правильным.
3. Это неправильно во многих отношениях. @danny: Пожалуйста, добавьте строку в таблицу заказов с помощью
9, 2, 0, 14/12/2009, 9
и запустите запрос еще раз, чтобы понять, почему.