嗨,这是我创建的用于从历史记录表中获取记录的查询。此查询工作正常,但执行时间过多,因为它从表中选择了两次数据,并且该表具有20密耳或以上的记录。所以我想优化它。我将尝试解释此查询的作用以及我想要实现的目的。 我想从表中为每个ID(ActivityId)选择两行,第一行是数据最小的地方,第二行是日期最大的地方,所以我可以看到在此期间发生了多少进展。现在我正在做的是首先选择日期最小的数据作为CTE,然后选择日期最大的数据作为CTE2。我可以在单个CTE中选择两行,但无法从两行中获得一条记录。就像我只需要最大日期行中的“进度和计划字段”,然后选择所有其他字段(大多数字段在两行中都是公用的)。所以我怎么能做到这一点。请根据需要进行澄清。
CTE:
WITH cte AS
(
SELECT Row_number() OVER (partition BY pmaph.activityid ORDER BY date) r1,
pma.planenddate AS planenddate ,
pma.planstartdate AS planstartdate,
pmaph.activityid,
pmaph.projectmilestoneactivproghist_id AS promileavtiid,
umd.uom_name AS uomname,
pmm.milestonename AS milestonename,
pma.activityname AS activityname ,
pmp.projectname AS projectname,
Replace((Rtrim(Ltrim(CONVERT(VARCHAR(12),Cast(pmaph.date AS DATETIME),106)))),' ','-') AS rdate,
Isnull(pmaph.actual_progress,0) AS actualprogress,
Isnull(pmaph.planned_progress,0) AS plannedprogress
FROM projectmilestoneactivityprogresshistory AS pmaph
LEFT JOIN dbo.pm_project AS pmp
ON pmaph.projectid=pmp.projectid
LEFT JOIN dbo.pm_activity AS pma
ON pmaph.activityid=pma.activityid
LEFT JOIN dbo.pm_milestone AS pmm
ON pmaph.milestoneid=pmm.milestoneid
LEFT JOIN dbo.uomdetail AS umd
ON pma.uom_id=umd.uom_id
WHERE pmaph.client_id=1030), cte2 AS( r2,isnull(pmaph.actual_progress,0) AS actualprogress, isnull(pmaph.planned_progress,0) AS plannedprogress, replace((rtrim(ltrim(CONVERT(varchar(12), cast(pmaph.date AS datetime),106)))),' ','-') AS rdate,pmaph.activityid FROM projectmilestoneactivityprogresshistory AS pmaph WHERE pmaph.client_id=1030)
SELECT cte2.rdate AS todate,
cte2.actualprogress AS end_actualprogress,
cte2.plannedprogress AS end_plannedprogress,
cte.actualprogress AS start_actualprogress,
cte.plannedprogress AS start_plannedprogress,
cte.rdate AS fromdate ,
cte.planenddate,
cte.planstartdate,
cte.activityid,
cte.uomname,
cte.milestonename,
cte.activityname,
cte.projectname
FROM cte
JOIN cte2
ON cte.activityid= cte2.activityid
WHERE cte.r1=1
AND cte2.r2=1