基于计数均匀分布顺序SQL结果
我有一些SQL结果,需要将它们划分为项目范围,并且计数均匀分布在多个任务中。做这件事的好方法是什么 我的数据是这样的基于计数均匀分布顺序SQL结果,sql,tsql,ssms,Sql,Tsql,Ssms,我有一些SQL结果,需要将它们划分为项目范围,并且计数均匀分布在多个任务中。做这件事的好方法是什么 我的数据是这样的 +------+-------+----------+ | Item | Count | ItmGroup | +------+-------+----------+ | 1A | 100 | 1 | | 1B | 25 | 1 | | 1C | 2 | 1 | | 1D | 6 |
+------+-------+----------+
| Item | Count | ItmGroup |
+------+-------+----------+
| 1A | 100 | 1 |
| 1B | 25 | 1 |
| 1C | 2 | 1 |
| 1D | 6 | 1 |
| 2A | 88 | 2 |
| 2B | 10 | 2 |
| 2C | 122 | 2 |
| 2D | 12 | 2 |
| 3A | 4 | 3 |
| 3B | 103 | 3 |
| 3C | 1 | 3 |
| 3D | 22 | 3 |
| 4A | 55 | 4 |
| 4B | 42 | 4 |
| 4C | 100 | 4 |
| 4D | 1 | 4 |
+------+-------+----------+
Item=项目代码。
Count=此上下文决定项目的流行程度。如果需要,可以使用此选项对项目进行排序。
ItmGroup-这是Itm列的父值。项目包含在一个组中
与我所看到的其他类似问题不同的是,我需要确定的范围不能超出表中显示的顺序。我们可以做从A1到B3的项目,换句话说,它们可以跨越ItmGroups,但它们必须按项目保持字母数字顺序
预期结果是平均分配总计数的项目范围
+------+-------+----------+
| FrItem | ToItem | TotCount|
+------+-------+----------+
| 1A | 2D | 134 |
| 3A | 3D | 130 |
(etc)
如果您对粗略估计感到满意,这将把数据分成两组 第一组将始终拥有尽可能多的记录,但不超过总数的一半(第2组将拥有其余记录)
如果您想让两个组的大小尽可能接近,那就要复杂得多。与公认的答案相同,除了在WITH CUMMARTIVECTE中声明批号和select语句的加法以防止余数
DECLARE @BatchCount NUMERIC(4,2) = 5.00;
WITH
cumulativeCte AS
(
SELECT
*,
SUM(r.[Count]) OVER (ORDER BY Item) AS cumulativeCount,
SUM(r.[Count]) OVER () AS totalCount
,CEILING(SUM(r.[Count]) OVER (ORDER BY IM.MMITNO ASC) / (SUM(r.[Count]) OVER () / @BatchCount)) AS BatchNo
FROM
records r
)
SELECT
MIN(c.Item) AS frItem,
MAX(c.Item) AS toItem,
SUM(c.[Count]) AS TotCount,
c.BatchNo
FROM
cumulativeCte c
GROUP BY
c.BatchNo
ORDER BY
c.BatchNo
所以
ItmGroup
与这个问题毫无关系?您是如何得到totCount
的?totCount将是项目1A-2D的计数之和。ItmGroup是表的聚集索引之一。这种情况可以简化为单个计算:n*cumulativeCount/totalCount
其中n
是groupsI是这样的,但在我的实际数据库中,无论我将'n'设置为什么,结果末尾都会额外留下1个。因此,如果n=30,则有31行。最后一行的TotCount=1。开始吧!谢谢你的帮助@马特贝利
GROUP BY
CASE WHEN cumulativeCount <= totalCount * 1/5 THEN 0
WHEN cumulativeCount <= totalCount * 2/5 THEN 1
WHEN cumulativeCount <= totalCount * 3/5 THEN 2
WHEN cumulativeCount <= totalCount * 4/5 THEN 3
ELSE 4 END
Item | Count GroupAsDefinedAbove IdealGroup
------+-------
1A | 4 1 1
2A | 5 2 1
3A | 8 2 2
DECLARE @BatchCount NUMERIC(4,2) = 5.00;
WITH
cumulativeCte AS
(
SELECT
*,
SUM(r.[Count]) OVER (ORDER BY Item) AS cumulativeCount,
SUM(r.[Count]) OVER () AS totalCount
,CEILING(SUM(r.[Count]) OVER (ORDER BY IM.MMITNO ASC) / (SUM(r.[Count]) OVER () / @BatchCount)) AS BatchNo
FROM
records r
)
SELECT
MIN(c.Item) AS frItem,
MAX(c.Item) AS toItem,
SUM(c.[Count]) AS TotCount,
c.BatchNo
FROM
cumulativeCte c
GROUP BY
c.BatchNo
ORDER BY
c.BatchNo