Как получить значение из следующей записи с условием WHERE в SQL? - PullRequest
0 голосов
/ 29 августа 2018

Я создал представление SQL с помощью Management Studio. Представление объединяет несколько таблиц и доступно моему приложению MVC. Таблицы связаны с прокатом автомобилей. Одна таблица содержит информацию об автомобиле, а другая таблица содержит информацию о бронировании, они объединяются с использованием представления.

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

Таблица: Автомобили

  • [Id]
  • [Регистрация]
  • [сделать]
  • [Модель]

Таблица: Бронирование

  • [Id]
  • [BookingStartDate]
  • [BookingEndDate]
  • [CarId]

Просмотр: CarBookings

SELECT  [C].[Id],
        [C].[Registration],
        [C].[Make],
        [C].[Model],
        [B].[BookingStartDate],
        [B].[BookingEndDate]

  FROM [Cars] AS C INNER JOIN [Bookings] AS B ON C.Id = B.CarId

Как я могу добавить в свой вид столбец, в котором будет отображаться информация о ближайшем следующем бронировании автомобиля? Любая помощь приветствуется.

Ответы [ 5 ]

0 голосов
/ 29 августа 2018

Если существующее представление делает то, что вы хотите (то есть все комбинации автомобилей и бронирований, кроме машин без бронирований, так как вы использовали внутреннее соединение), и вы просто хотите проецировать «следующий» заказ, который, как я предполагаю, ссылается на текущую дату,

Вы можете добавить левое объединение к запросу, который запрашивает «следующее» бронирование для каждого автомобиля, и создать столбец, который определяет условия, когда он соответствует следующей записи.

Логика левого соединения:

  1. Получите все будущие заказы на машину (это где фильтр)
  2. Возьмите следующий (минимальное время бронирования).
  3. Регистрация - на дату бронирования и carId (теперь, если будет два одинаковых забронировав за автомобиль, вы получите оба в следующем матче, так как присоединяйтесь к условие будет применяться к обоим).

    select 
    a.* , 
    b.* ,
    case when c.carId is not null then 1 else 0 end as IsNext
    from cars a
    inner join bookings b
        on a.id = b.carid
    left join (select carid , min(bookingStartDate) bookingStartDate from bookings where bookingStartDate > now() group by carid) c
        on b.carId = c.carId
        and b.bookingStartDate = c.bookingStartDate
    
0 голосов
/ 29 августа 2018

Ниже Query выдаст все бронирование для определенного автомобиля. Если вы хотите только следующий, тогда вам нужно использовать Row_number.

SELECT  [C].[Id],
        [C].[Registration],
        [C].[Make],
        [C].[Model],
        [B].[BookingStartDate],
        [B].[BookingEndDate]

  FROM [Cars] AS C 
  INNER JOIN [Bookings] AS B ON C.Id = B.CarId
  WHERE [B].[BookingStartDate] >= GETDATE()
  ORDER BY [B].[BookingStartDate]
0 голосов
/ 29 августа 2018

Вот запрос, который должен генерировать результаты, которые вы хотите. В CTE я использую сводный запрос, чтобы получить самую последнюю и вторую самую последнюю запись о бронировании для каждой CarId. Затем мы присоединяем этот CTE к таблице Car аналогичным образом, который вы уже делали.

WITH cte AS (
    SELECT
        CarId,
        MAX(CASE WHEN rn = 1 THEN BookingStartDate END) AS BookingStartDate,
        MAX(CASE WHEN rn = 1 THEN BookingEndDate   END) AS BookingEndDate,
        MAX(CASE WHEN rn = 2 THEN BookingStartDate END) AS NextBookingStartDate,
        MAX(CASE WHEN rn = 2 THEN BookingEndDate   END) AS NextBookingEndDate
    FROM
    (
        SELECT CarId, BookingStartDate, BookingEndDate,
            ROW_NUMBER() OVER (PARTITION BY CarId ORDER BY BookingStartDate DESC) rn
        FROM Bookings
    ) t
    WHERE rn <= 2
    GROUP BY CarId
)

SELECT
    c.Id,
    c.Registration,
    c.Make,
    c.Model,
    b.BookingStartDate,
    b.BookingEndDate,
    b.NextBookingStartDate,
    b.NextBookingEndDate
FROM Cars c
INNER JOIN cte b
    ON c.Id = b.CarId;
0 голосов
/ 29 августа 2018

Как отметил Тим в комментариях, ваш запрос alreadi дает вам все заказы, но если вам нужно в другом столбце, тогда может быть lead() - это то, что вам нужно?

SELECT  C.Id,
B.BookingStartDate,
B.BookingEndDate,
lead(BookingStartDate) over(partition by C.Id order by B.BookingEndDate) nextdt
FROM Cars AS C INNER JOIN Bookings AS B ON C.Id = B.CarId
0 голосов
/ 29 августа 2018

Использование LEAD() (sql server 2012 г.в.)

select c.*, b.BookingStartDate, b.BookingEndDate,
       lead(bookingstartdate) over (partition by carid order by BookingStartDate) as nextbooking
from cars c
inner join bookings b
on c.id = b.carid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...