如何使用SQL查询根据条件获取下一条记录?

时间:2019-02-04 14:59:35

标签: sql sql-server

我有一个租车表,其中记录了租车Onhire的所有日期以及退还Offhire的时间。我被要求在结果表中提供下一个或续聘的公司名称,但我不确定该怎么做。雇用表的结构如下:

---------------
| Hire        |
---------------
| Id          |
| CarId       |
| Onhire      |
| Offhire     |
| HireCompany |
|-------------|

如果我对该表运行基本选择,则会看到以下数据。我添加了WHERE来撤回一辆仍在出租的特定汽车,并在随后不久(我使用英国日期格式)进行跟进出租。

Id  |  CarId |  Onhire     |  Offhire    |  HireCompany
-------------------------------------------------------
10  |  272   |  2019-01-01 |  2019-03-01 |  Company A
11  |  272   |  2019-03-02 |  2019-04-01 |  Company B
-------------------------------------------------------

如您所见,这辆车目前正在出租,直到01/03/2019,但是在那之后,它将在02/03/2019出租到Company B。我需要查询以表明汽车目前正在出租,但在名为ForwardHire(或其他名称)的列中,显示有要出租的NEXT公司以及显示下一个出租开始日期的列

因此,我的查询将产生以下所需结果:

Id  |  CarId |  Onhire     |  Offhire    |  ForwardHire |  ForwardHireDate
---------------------------------------------------------------------------
10  |  272   |  2019-01-01 |  2019-03-01 |  Company B   |  2019-03-02
  

注意:我已经知道如何从“聘用”中返回单个结果   使用外部应用程序的表,建议是在另一个线程中得到的。

我希望我的问题有意义并且有人可以提供帮助。在SQL查询方面,这对我来说是第一个,因此感谢您提供任何建议和指导。

4 个答案:

答案 0 :(得分:3)

您是否正在寻找moment of methods函数? :

SELECT h.*
FROM (SELECT h.*,
             LEAD(HireCompany) OVER (PARTITION BY CarID ORDER BY Id) AS ForwardHire,
             LEAD(Onhire) OVER (PARTITION BY CarID ORDER BY Id) AS ForwardHireDate
      FROM Hire h
     ) h
WHERE ForwardHire IS NOT NULL AND ForwardHireDate IS NOT NULL;

答案 1 :(得分:3)

使用OUTER APPLY:

SELECT
    H.*,
    T.ForwardHire,
    T.ForwardHireDate
FROM
    Hire AS H
    OUTER APPLY (
        SELECT TOP 1                        -- Just the next record
            ForwardHire = F.HireCompany,
            ForwardHireDate = F.OnHire
        FROM
            Hire AS F
        WHERE
            H.CarId = F.CarId AND           -- With the same car
            F.OnHire > H.OffHire            -- With later OnHire
        ORDER BY
            F.OnHire ASC                    -- Sorted by OnHire (closeste one first)
        ) AS T

答案 2 :(得分:2)

您只想要lead()吗?

select h.*,
       lead(h.hirecompany) over (partition by h.carid order by h.onhire) as next_hirecompany
from hire h;

注意:即使有差距,这也会退还下一家公司。如果您要与下一家“相邻”公司,那么我建议您使用left join

select h.*, hnext.hirecompany as next_hirecompany
from hire h left join
     hire hnext
     on hnext.carid = h.carid and
        hnext.onhire = dateadd(day, 1, h.offhire);

答案 3 :(得分:1)

自我将hire表加入到下一个onhire日期的行:

select 
  h1.*,
  h2.hirecompany ForwardHire 
  h2.onhire ForwardHireDate
from hire h1 left join hire h2
on 
  (h2.carid = h1.carid) 
  and 
  (h2.onhire = (select min(onhire) from hire where carid = h1.carid and onhire > h1.offhire) )
where 
  h1.carid = 272
  and
  curdate() between h1.onhire and h1.offhire