sql - Sql Server:在保留行分组的同时对数据集进行分区
问题描述
我有一个查询,它返回根据两列分组的行,如下所示:
Student_ID Module_ID Assignment_date Assignment_grade
1 2 2010-01-01 C
1 2 2012-02-02 E
1 2 2013-03-02 A*
3 6 2013-03-02 B
3 6 2013-03-02 B
我试图通过并行处理结果集来提高性能。为此,我需要将结果集划分为大小接近相等的部分,同时确保行分组不会分布在多个分区中,因为分组对于处理很重要。这必须使用多个查询来完成,而不是一个查询然后对结果进行分区,因为在查询数据后对行进行分区会产生过多的开销(目的是将每个查询分配给一个SqlDataReader
)。
通常,我会使用ROW_NUMBER()
将数字分配给行,然后将 WHERE 子句添加到每个查询中,类似于,WHERE row_number > lowerbound AND row_number < upperbound
但这可能会导致数据集在分组中间被拆分。
如何确保我使用的每个查询都选择数据的不同部分,并且结果中的每个分组都包含分组中的所有行?
我想过使用DENSE_RANK()
为每个分组分配一个 ID,但我不知道如何将它与行号结合使用来实现我想要的结果。
此示例中的理想结果将是一个返回以下内容的查询:
Student_ID Module_ID Assignment_date Assignment_grade
1 2 2010-01-01 C
1 2 2012-02-02 E
1 2 2013-03-02 A*
另一个返回这个的查询:
Student_ID Module_ID Assignment_date Assignment_grade
3 6 2013-03-02 B
3 6 2013-03-02 B
解决方案
您可以按如下方式使用 WINDOWS 功能:
WITH CTE AS (SELECT T.*,
COUNT(1) OVER () AS CNT,
ROW_NUMBER() OVER (ORDER BY STUDENT_ID, MODULE_ID, ASSIGNMENT_DATE) AS RN,
DENSE_RANK() OVER (ORDER BY STUDENT_ID, MODULE_ID) AS DR
FROM YOUR_TABLE T)
SELECT T1.*
FROM CTE T
-- WHERE DR <= (SELECT MAX(DR) FROM CTE T2 WHERE RN <= CEIL(CNT/2)) -- FIRST PART
-- WHERE DR >= (SELECT MIN(DR) FROM CTE T2 WHERE RN > CEIL(CNT/2)) -- SECOND PART
推荐阅读
- c++ - 方便的 Vector3f 类
- string - 如何剖析和解析lua中的字符串?
- perl - 如何使用 HTML::TreeBuilder::XPath 循环 findnodes() 的结果
- python - HTTP服务器启动后台python脚本无阻塞
- datetime - 如何使用 DateTimeFormatter 忽略毫秒和格式
- javascript - Firebase 实时数据库 - 在迭代数组时获取数据
- excel - 包括 SUB 而 .SAVEAS
- matlab - 预测 SVM 回归的测试样本响应
- python - python清理文本数据
- node.js - 当用户从数据库中删除时删除帖子