SQL用户定义函数查找上一条记录

时间:2015-12-10 16:44:54

标签: sql sql-server

我一直在尝试从数据集中的先前记录中获取数据,并使用该先前记录中的一些数据。这些记录与我的资产ID相关联,我想我已经接近但我现在需要一些专家建议来克服最后的障碍。 下面是我提出的声明,但我得到一个错误,我可以看到错误来自哪里,但我不知道如何绕过它。 我的代码是:

SELECT location,
(SELECT TOP (1) week_number
 FROM dbo.tbl_job_planning AS l2
 WHERE week_number < dbo.tbl_job_planning.week_number
 ORDER BY week_number DESC) AS prev_week
FROM  dbo.tbl_job_planning
WHERE fleet_no = @fleet AND week_number = prev_week
ORDER BY date_starting DESC

问题在于,prev_week不是我表格中的实际列,它是即时制作的#39;。请有人指出我正确的方向。

3 个答案:

答案 0 :(得分:1)

WITH data_with_rn AS
(
  SELECT location, fleet_no, week_number,
       ROW_NUMBER() (PARTITION BY fleet_no, ORDER BY week_number DESC) as week_rn
  FROM dbo.tbl_job_planning
)
SELECT base.location, base.date_starting, prior.week_number as prev_week
FROM data_with_rn base
LEFT JOIN data_with_rn prior ON prior.week_rn = base.week_rn - 1  AND base.fleet_no = prior.fleet_no
WHERE base.fleet_no = @fleet
ORDER BY base.date_starting DESC

答案 1 :(得分:1)

我认为您可以使用LAG函数(可从SQL Server 2012获得)避免自加入:

with WeekOrder AS (
    select C.location, C.fleet_no, C.date_starting, LAG(location, 1, NULL) OVER (Partition By fleet_no Order By week_number Asc) AS PrevLocation
    FROM dbo.tbl_job_planning C
)
select * 
from  WeekOrder C
Where       C.fleet_no = @fleetNo
    and PrevLocation IS NOT NULL
Order By    C.date_starting Desc

此外,查询稍微小一点,应该有比自连接版本更好的执行计划。

答案 2 :(得分:0)

您可以使用ROW_NUMBER()窗口函数和fleet_no上的分区来订购周。

这应该适合你:

;With WeekOrder As
(
    Select  *, Row_Number Over (Partition By fleet_no Order By week_number Asc) As Row_Number
    From    tbl_job_planning
)
Select      C.location, P.week_number As Prev_week
From        WeekOrder   C
Left Join   WeekOrder   P   On  C.Row_Number - 1 = P.Row_Number
                            And C.fleet_no = P.fleet_no
Where       C.fleet_no = @fleet
Order By    C.date_starting Desc