如何在SQL中使用WHERE条件从下一条记录中获取值?

时间:2018-08-29 09:16:12

标签: sql model-view-controller

我已经使用Management Studio创建了一个SQL视图。该视图将几个表连接在一起,并由我的MVC应用程序访问。这些表与租车有关。一个表保存了汽车的详细信息,而另一个表保存了预订信息,这些信息通过视图结合在一起。

该视图可以正常工作,但是还要求我添加一列,以显示汽车的下一次即时预订。这意味着我需要一列来显示汽车ID匹配的下一个预订开始日期。

表格:汽车

  • [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 :(得分:2)

使用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

答案 1 :(得分:1)

这是一个查询,应生成所需的结果。在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;

答案 2 :(得分:1)

蒂姆在评论中提到,您的查询已经为您提供了所有预订,但是如果您需要在另一列中,则可能是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

答案 3 :(得分:0)

如果现有视图满足您的要求(这是汽车和预订的所有组合,但由于您使用内部联接而没有预订的汽车除外), 并且您只想投影“下一个”顺序(我假设是对当前日期时间的引用),

您可以在查询中添加左联接,以拉动每辆车的“下一个”预订,并创建一列以在与下一条记录匹配时对其进行调节。

左联接逻辑:

  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
    

答案 4 :(得分:-1)

在下面的查询中,将提供特定汽车即将推出的所有预订。如果只想要下一个,则应该使用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]