我想根据某些列对行进行分组,即如果这些列中的数据在连续行中相同,那么为它们分配相同的组号,并且如果其更改,则分配新列。这变得很复杂,因为列中的相同数据可能会出现在其他某些行中,因此它们必须被赋予另一个组号,因为它们不在具有前一组的连续行中。 为了达到这个目的,我使用了cte,并且它也给出了正确的输出,但速度很慢,因此迭代超过75k +行大约需要15分钟。我使用的代码是:递归cte工作很慢
WITH
cte AS (SELECT ROW_NUMBER() OVER (ORDER BY Patient_ID, Opnamenummer, SPECIALISMEN, Opnametype, OntslagDatumTijd) AS RowNumber,
Opnamenummer, Patient_ID, AfdelingsCode, Opnamedatum, Opnamedatumtijd, Ontslagdatum, Ontslagdatumtijd, IsSpoedopname, OpnameType, IsNuOpgenomen, SpecialismeCode, Specialismen
FROM t_opnames)
SELECT * INTO #ttt FROM cte;
WITH cte2 AS (SELECT TOP 1 RowNumber,
1 AS GroupNumber,
Opnamenummer, Patient_ID, AfdelingsCode, Opnamedatum, Opnamedatumtijd, Ontslagdatum, Ontslagdatumtijd, IsSpoedopname, OpnameType, IsNuOpgenomen, SpecialismeCode, Specialismen
FROM #ttt
ORDER BY RowNumber
UNION ALL
SELECT c1.RowNumber,
CASE
WHEN c2.Afdelingscode <> c1.Afdelingscode
OR c2.Patient_ID <> c1.Patient_ID
OR c2.Opnametype <> c1.Opnametype
THEN c2.GroupNumber + 1
ELSE c2.GroupNumber
END AS GroupNumber,
c1.Opnamenummer,c1.Patient_ID,c1.AfdelingsCode,c1.Opnamedatum,c1.Opnamedatumtijd,c1.Ontslagdatum,c1.Ontslagdatumtijd,c1.IsSpoedopname,c1.OpnameType,c1.IsNuOpgenomen, SpecialismeCode, Specialismen
FROM cte2 c2
JOIN #ttt c1 ON c1.RowNumber = c2.RowNumber + 1
)
SELECT *
FROM cte2
OPTION (MAXRECURSION 0) ;
DROP TABLE #ttt
我试图通过将cte的输出放在临时表中来提高性能。这增加了表现,但仍然太慢。那么,我该如何提高这个代码的性能到,在10秒钟内运行75k +记录呢?取消查询前的输出是:Screenshot。从图像中可以看出,RowNumber 3,5和6中的数据在列Afdelingscode,Patient_ID和Opnametype中是相同的,但由于行的并发,它们具有不同的GroupNumber。
嗨,感谢您的答复。请看这个小提琴[链接](http://sqlfiddle.com/#!6/6aac5/1/0)。我用样本数据创建了这个小提琴。我无法使用分区,因为它会对行进行无组织,并且我将不得不在最后一个select语句中再次使用Order By,这会再次降低性能。我已经尝试过了。 – phreq
在小提琴: 时间与您的解决方案4ms的补临时表+ 6ms的运行SELECT + 2ms的DROP TABLE(12毫秒计) 时间与您的解决方案,但没有临时表:8ms的 时间与分区和ORDER BY:3ms的 请注意即: 小提琴只包含10行。这是一个小数据集。 75k行,执行计划可以完全不同,所以这不是一个很大的帮助。 看一看,如果你有分区的索引/索引和按列排序,如果是的话,索引是什么。 此外,请通过解决方案(包括查询)发布解决方案的执行计划和分区。谢谢 –
我在表中有索引,我在列“ID”上有一个聚簇索引。因此,如果我应该在“Order By”列中添加索引,这会很好,集群还是非集群? – phreq