You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在关联且按日期排序的SQL查询中返回当前行与上一行

解决你的班组工作量对比查询问题

首先,你的核心问题在于子查询没有关联外层查询的当前班组ID,导致子查询返回的是所有符合日期条件的总工作量,而不是对应班组的前一日数据。下面给你两种可行的解决方案:


方案1:修改关联子查询(兼容多数数据库,包括Access)

我们需要给外层的Spread_Crew表起一个别名,然后在子查询中明确关联这个别名的ID,确保子查询只返回当前班组的前一日数据。同时调整日期条件,确保查询的是前一日的工作量(如果你的[Report Date]是参数,替换成对应的日期逻辑即可)。

修改后的完整SQL如下:

SELECT 
    sc.Description,
    Sum(Abs(dp.Station_Number_Begin - dp.Station_Number_End)) AS [Feet Total],
    sc.Hourly_Employee_Count AS [Hourly],
    sc.Salary_Employee_Count AS [Salary],
    (sc.Hourly_Employee_Count + sc.Salary_Employee_Count)*10 AS [Weekly Hours],
    (Date() - sc.Actual_Start_Date) AS [Crew Days to Date],
    Round(([Feet Total]/ [Crew Days to Date]),0) AS [FT/Day],
    -- 关联子查询:只返回当前班组前一日的工作量
    (SELECT 
         Sum(Abs(dp_prev.Station_Number_Begin - dp_prev.Station_Number_End))
     FROM Daily_Progress dp_prev
     WHERE dp_prev.Spread_Crew_Id = sc.ID  -- 关键:关联外层的当前班组ID
       AND dp_prev.PROGRESS_DATE = Date() - 1)  -- 取前一日数据,可根据需求替换为[Report Date]-1
    AS [Previous Footage]
FROM Spread_Crew sc
LEFT JOIN Daily_Progress dp ON sc.ID = dp.Spread_Crew_Id
WHERE sc.Print_On_Daily_Report = True  -- 把HAVING改成WHERE更高效,因为是筛选分组前的数据
GROUP BY 
    sc.Description,
    sc.Hourly_Employee_Count,
    sc.Salary_Employee_Count,
    sc.Sort_Order,
    sc.Actual_Start_Date
ORDER BY sc.Sort_Order;

关键修改点:

  • 给外层表起别名sc和dp,让子查询可以明确关联当前班组的sc.ID
  • 子查询不再重复Join Spread_Crew,直接通过dp_prev.Spread_Crew_Id = sc.ID关联当前班组
  • 将原HAVING中的Print_On_Daily_Report=True移到WHERE子句,提升查询效率(因为分组前筛选比分组后更高效)

方案2:使用窗口函数(适用于支持LAG()的数据库,如SQL Server、PostgreSQL等)

如果你的数据库支持窗口函数,用LAG()函数可以更简洁地获取上一行数据,无需子查询:

WITH CrewDailyStats AS (
    SELECT 
        sc.ID,
        sc.Description,
        sc.Hourly_Employee_Count,
        sc.Salary_Employee_Count,
        sc.Actual_Start_Date,
        sc.Sort_Order,
        Sum(Abs(dp.Station_Number_Begin - dp.Station_Number_End)) AS [Feet Total],
        dp.PROGRESS_DATE
    FROM Spread_Crew sc
    LEFT JOIN Daily_Progress dp ON sc.ID = dp.Spread_Crew_Id
    WHERE sc.Print_On_Daily_Report = True
    GROUP BY 
        sc.ID, sc.Description, sc.Hourly_Employee_Count, sc.Salary_Employee_Count,
        sc.Actual_Start_Date, sc.Sort_Order, dp.PROGRESS_DATE
)
SELECT 
    Description,
    [Feet Total],
    Hourly_Employee_Count AS [Hourly],
    Salary_Employee_Count AS [Salary],
    (Hourly_Employee_Count + Salary_Employee_Count)*10 AS [Weekly Hours],
    (Date() - Actual_Start_Date) AS [Crew Days to Date],
    Round(([Feet Total]/ [Crew Days to Date]),0) AS [FT/Day],
    -- 按班组分区,按日期排序,获取上一日的工作量
    LAG([Feet Total], 1) OVER (PARTITION BY ID ORDER BY PROGRESS_DATE) AS [Previous Footage]
FROM CrewDailyStats
ORDER BY Sort_Order, PROGRESS_DATE;

优势:

  • 代码更简洁,逻辑更清晰
  • 避免了子查询的重复计算,性能更优

内容的提问来源于stack exchange,提问作者kcabral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:49:56