From 5adcb0c884b376abe8aef76a528ce3c07950a32a Mon Sep 17 00:00:00 2001
From: Denis <epselent-dev@yandex.ru>
Date: Sun, 4 Aug 2024 16:40:29 +0500
Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5?=
 =?UTF-8?q?=D0=BB=D0=B0=D0=BB=20sql=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81?=
 =?UTF-8?q?=20=D0=BA=20=D0=B1=D0=B4=20=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B8?=
 =?UTF-8?q?=D1=81=D0=BA=20last=20=D0=B8=20next=20booking?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../shareit/booking/BookingRepository.java    | 20 +++++++++++--------
 .../shareit/item/service/ItemServiceImpl.java | 18 ++++++-----------
 2 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java
index 0f57bf3..2fc0e0f 100644
--- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java
+++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java
@@ -34,18 +34,22 @@ public interface BookingRepository extends JpaRepository<Booking, Long>, Queryds
     Optional<Booking> findByItemNextBooking(Long itemId, LocalDateTime now);
 
     @Query(value = """
-            select b from Booking as b where b.item.id in ?1
-            and b.status='APPROVED'
-            and b.startTime < ?2
-            order by b.startTime desc
+            select b from Booking as b
+            join(select b.item.id as item, max(b.startTime) as firstStartTime
+            from Booking as b
+            where b.startTime < ?2 and b.status='APPROVED'
+            group by b.item.id) as subquery on b.item.id=subquery.item and b.startTime = subquery.firstStartTime
+            where b.item.id in ?1
             """)
     List<Booking> findAllByItemsLastBooking(List<Long> itemIds, LocalDateTime now);
 
     @Query(value = """
-            select b from Booking as b where b.item.id in ?1
-            and b.status='APPROVED'
-            and b.startTime > ?2
-            order by b.startTime asc
+            select b from Booking as b
+            join(select b.item.id as item, min(b.startTime) as firstStartTime
+            from Booking as b
+            where b.startTime > ?2 and b.status='APPROVED'
+            group by b.item.id) as subquery on b.item.id=subquery.item and b.startTime = subquery.firstStartTime
+            where b.item.id in ?1
             """)
     List<Booking> findAllByItemsNextBooking(List<Long> itemIds, LocalDateTime now);
 
diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java
index 81ae057..673f403 100644
--- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java
+++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java
@@ -90,23 +90,17 @@ public List<ItemInfoDto> getAllOfOwner(Long userId) {
                 .findAllByItemsLastBooking(new ArrayList<>(itemMap.keySet()), LocalDateTime.now());
         List<Booking> nextBookings = bookingRepository
                 .findAllByItemsNextBooking(new ArrayList<>(itemMap.keySet()), LocalDateTime.now());
-        Map<Long, List<Booking>> lastBookingsByItem = lastBookings.stream()
-                .collect(Collectors.groupingBy(booking -> booking.getItem().getId()));
-        Map<Long, List<Booking>> nextBookingsByItem = nextBookings.stream()
-                .collect(Collectors.groupingBy(booking -> booking.getItem().getId()));
-        Map<Long, Booking> lastBookingByItem = lastBookingsByItem.keySet().stream()
-                .map(id -> lastBookingsByItem.get(id).getFirst())
-                .collect(Collectors.toMap(booking -> booking.getItem().getId(), item -> item));
-        Map<Long, Booking> nextBookingByItem = nextBookingsByItem.keySet().stream()
-                .map(id -> nextBookingsByItem.get(id).getFirst())
-                .collect(Collectors.toMap(booking -> booking.getItem().getId(), item -> item));
+        Map<Long, Booking> next = nextBookings.stream()
+                .collect(Collectors.toMap(booking -> booking.getItem().getId(), booking -> booking));
+        Map<Long, Booking> last = lastBookings.stream()
+                .collect(Collectors.toMap(booking -> booking.getItem().getId(), booking -> booking));
         List<Comment> comments = commentRepository.findAllByItemIdIn(new ArrayList<>(itemMap.keySet()));
         Map<Long, List<Comment>> commentsByItem = comments.stream()
                 .collect(Collectors.groupingBy(comment -> comment.getItem().getId()));
         return itemMap.keySet().stream()
                 .map(id -> itemMapper.toInfoDto(itemMap.get(id),
-                        lastBookingByItem.get(id),
-                        nextBookingByItem.get(id),
+                        last.get(id),
+                        next.get(id),
                         commentsByItem.get(id)))
                 .toList();
     }