代码之家  ›  专栏  ›  技术社区  ›  Yanayaya

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

  •  2
  • Yanayaya  · 技术社区  · 6 年前

    我已经使用managementstudio创建了一个SQL视图。视图将两个表连接在一起,并由我的MVC应用程序访问。这些表格与租车有关。一个表保存车辆详细信息,而另一个表保存预订信息,这些信息使用视图连接。

    视图工作没有问题,但我也被要求添加一列,显示下一个立即预订的汽车。这意味着,我需要一个列来显示下一个预订开始日期的汽车Id匹配。

    表:汽车

    • [身份证]
    • [注册]
    • [型号]

    • [身份证]
    • [预订开始日期]
    • [预订日期]
    • [加勒比]

    视图: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 回复  |  直到 6 年前
        1
  •  1
  •   Oto Shavadze    6 年前

    正如Tim在评论中提到的,您的查询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
    
        2
  •  2
  •   JohnHC    6 年前

    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
    
        3
  •  1
  •   Tim Biegeleisen    6 年前

    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;
    
        4
  •  0
  •   Y.S    6 年前

    如果现有视图符合您的要求(这是所有汽车和预订的组合,但由于使用了内部联接,因此没有预订的汽车除外), 你只需要投射“下一个”的顺序,我假设引用当前的日期和时间,

    您可以向查询中添加一个左连接,该查询提取每辆车的“下一个”预订,并创建一个列,在它与下一个记录匹配时对其进行限制。

    左连接逻辑:

    1. 获取每辆车的所有未来预订(这是where过滤器)
    2. 下一个(最短预订时间)。
    3. 每辆车的预订,您将获得作为下一个匹配,因为加入 条件将适用于两者)。

      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
      
        5
  •  -1
  •   JERRY    6 年前

    下面的查询将给即将到来的所有预订的一个特定的汽车。如果你只想要下一个,那么你应该用排号。

    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]