#java #postgresql #hibernate #datetime #greatest-n-per-group
#java #postgresql #переход в спящий режим #дата и время #наибольшее число на группу
Вопрос:
Я хочу показать пользователю его сводку покупок из каждого магазина, вплоть до первых 3 покупок из каждого магазина. Для простоты количество покупок не настраивается. Итак, это не первое N, а первые 3
Допустим, у меня есть эти таблицы с этими столбцами
Store
id
name
Product
id
name
storeId
price
Purchase
id
userId
productId
count
purchaseTime
Это то, что я хочу отобразить
-----------------------------------------------
| store | product | count | price |
-----------------------------------------------
| disney | stitch doll | 1 | 30 |
| | donald cap | 3 | 15 |
| | ticket | 2 | 100 |
-----------------------------------------------
| universal | iron man figure | 1 | 100 |
| | batman figure | 1 | 90 |
-----------------------------------------------
Предпочтительно, если пользователь покупает donald caps для 2 отдельных покупок (предполагается, что цена никогда не изменится), количество покупок будет объединено
например: если пользователь покупает 2 заглушки Дональда, а затем 1 заглушку, результатом будет 3 заглушки Дональда — вместо 2 заглушек Дональда и 1 заглушки Дональда
Я использую hibernate и postgresql
Я даже не знаю, с чего начать, в частности, как ограничить количество покупок в каждом магазине до 3 для каждого магазина
Любой намек, решение psudo или решения будут оценены
Спасибо
Примечание: К сожалению, с моей стороны есть серьезная оплошность. Я думаю, что хочу получить каждое резюме в 1 строке
Например
id | Store | Product1 | count1 | price1 | Product2 | count2 | price2 | Product3 | count3 | price3
----------------------------------------------------------------------------------------------------------------------------------
2 | Disney | stitch doll | 1 | 30 | donald cap | 3 | 15 | ticket | 2 | 100
5 | Universal | iron man figure | 1 | 100 | batman figure | 1 | 90 | null | null | null
Причина в том, что мне нужно разбить результат на страницы — отобразить 10 сводок покупок на странице
Если каждая сводка возвращает 1-3 строки, трудно определить результат на следующей странице
Комментарии:
1. » количество покупок будет объединено «, так что использование
sum(count)
для всех этих покупок? Или простоcount(*)
. Как насчет столбца цены? Должно ли это показывать цену за одну покупку или сумму всех покупок продуктов, например, рассчитывается ли цена 15 за 3 колпачка как 3 * 5 или это цена за один колпачок?2. Сумма (количество). Цена будет индивидуальной. Спасибо
3. @Budi Как ваш вопрос связан с
hibernate
?4. Итак, вы хотите объединить покупки для каждой комбинации продукта / магазина. Вы хотите ограничить «покупку» 3 после этой агрегации? Или до агрегирования? т. Е. Если бы это было сделано раньше, 3 покупки одного и того же продукта отображались бы в виде одной строки в выходных данных.
5. Sql может быть записан как hql (язык запросов гибернации). После нахождения правильного sql я могу переименовать его в hql (по причине переносимости)
Ответ №1:
Вы могли бы использовать боковое объединение для получения первых 3 покупок в каждом магазине:
select s.name, p.*
from store s
cross join lateral (
select pr.name as product, pu.count, pr.price
from purchase pu
inner join product pr on pr.id = pu.productid
where pr.storeid = s.id and pu.userid = ?
order by pu.purchasetime
limit 3
) p
В качестве альтернативы вы можете использовать row_number()
:
select *
from (
select pr.name as product, pu.count, pr.price,
row_number() over(partition by s.id order by pu.purchasetime) rn
from purchase pu
inner join product pr on pr.id = pu.productid
inner join store s on s.id = pr.storeid
where pu.userid = ?
) t
where rn <= 3
Комментарии:
1. Я получил эту ОШИБКУ: столбец «pr.price» должен отображаться в предложении GROUP BY или использоваться в агрегатной функции во 2-м решении, и та же ошибка с «pr.name » в 1-м решении. Спасибо
2. @Budi: этот запрос не может вызвать эту ошибку. Вероятно, вы включили это в другой запрос, содержащий
group by
предложение.3. Я получил эту ошибку после того, как я адаптировал имена, чтобы отразить мою фактическую базу данных. В любом случае, с моей стороны есть оплошность. Я обновил свое требование. Если у вас есть время, пожалуйста, дайте мне подсказку, как с этим справиться. Спасибо