我有需要分解为项目范围的SQL结果,并且计数在多个任务之间平均分配。什么是这样做的好方法?
我的数据如下。
+------+-------+----------+
| 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 =在这种情况下,它确定了商品的受欢迎程度。如果需要,可以将其用于RANK项目。 ItmGroup-这是Itm列的父值。项目包含在组中。
这与我已经查看过的其他类似问题的不同之处在于,我需要确定的范围不能超出表中显示的顺序。我们可以执行从A1到B3的项目范围,换句话说,它们可以跨越ItmGroups,但是它们必须按Item保持字母数字顺序。
预期结果将是均匀分布总计数的项目范围。
+------+-------+----------+
| FrItem | ToItem | TotCount|
+------+-------+----------+
| 1A | 2D | 134 |
| 3A | 3D | 130 |
(etc)
答案 0 :(得分:1)
只要您对粗略的估算感到满意,就可以将数据分成两组。
第一个组将始终具有尽可能多的记录,但 不超过 个总数的一半(第二组将拥有其余记录) 。
WITH
cumulative AS
(
SELECT
*,
SUM([Count]) OVER (ORDER BY Item) AS cumulativeCount,
SUM([Count]) OVER () AS totalCount
FROM
yourData
)
SELECT
MIN(item) AS frItem,
MAX(item) AS toItem,
SUM([Count]) AS TotCount
FROM
cumulative
GROUP BY
CASE WHEN cumulativeCount <= totalCount / 2 THEN 0 ELSE 1 END
ORDER BY
CASE WHEN cumulativeCount <= totalCount / 2 THEN 0 ELSE 1 END
要将数据分成5部分,这很相似...
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
如果您想要使两组的尺寸尽可能接近的东西,那就复杂得多。
答案 1 :(得分:0)
与接受的答案相同,除了在WITHcumulativeCte中声明批号和在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