按记录计数将子记录划分为簇,而不拆分父ID

时间:2018-02-22 16:53:26

标签: sql-server sql-server-2008 tsql ssis

我正在尝试构建一个流程,将一组事务拆分为大致相同大小的组,以便于分块数据。

实体可以有多个交易。为了这个问题,让我们说一个交易可以有多个与之相关的金额。这是胡说八道,但它保留了所有数字。

我想将总交易分成集群,但我无法划分实体。所有实体的交易都需要一起处理。

这是一个示例数据集:

CREATE TABLE #sorting
(
 Entity_ID bigint
,Trans_ID bigint
,Trans_Amt money
);

INSERT #sorting
(
 Entity_ID 
,Trans_ID 
,Trans_Amt 
)
VALUES
  (321, 456, 1.00),
  (321, 457, 2.00),
  (5309, 458, 10.00),
  (321, 459, 1.50),
  (5309, 460, 2.50),
  (321, 461, 10.50),
  (5309, 462, 3.00),
  (321, 463, 4.00),
  (321, 465, 6.00),
  (867, 466, 7.00),
  (321, 467, 9.00),
  (867, 466, 22.00),
  (321, 468, 4.20)

SELECT
  Entity_ID
  ,COUNT(*) AS RecCnt
FROM #sorting
GROUP BY Entity_ID;

SELECT 
  *
FROM #sorting
ORDER BY 
 Entity_ID 
,Trans_ID 
,Trans_Amt DESC;


IF OBJECT_ID('tempdb..#sorting', 'U') IS NOT NULL
  DROP TABLE #sorting;

第一个查询的结果集如下所示:

Entity_ID   RecCnt
  321         8
  867         2
 5309         3

我的梦想结果集看起来像这样(它不需要记录计数,只需要Entity_ID和组成员资格。记录计数包括在下面的解释中):

Entity_ID   RecCnt  Group_ID
  321         8         1
  867         2         2
 5309         3         2

Entity_ID 321本身属于一个组,因为它包含超过一半的事务。 Entity_IDs 867和5309聚集在一起,因为它们的总交易数或多或少等于321中的总数。

在现实生活中,我将几百万笔交易分成8个或10个集群。

我尝试过NTILE()和一些不成功的子查询的不同排列,但我认为我已经陷入了太深的困境。如果有人可以伸出援助之手,我将非常感激。

编辑:20180223 - 将目标从并行处理更改为数据分块。

1 个答案:

答案 0 :(得分:0)

问题与此类似 Split set of values into 5 groups each group should have sum(count) evenly

我根据你的问题从这个问题改变了答案。

DECLARE @GroupCount INT = 2

;WITH Data AS (
    SELECT
      Entity_ID
      ,COUNT(*) AS RecCnt
    FROM #sorting
    GROUP BY Entity_ID
),
CTE AS (
    SELECT * ,
        RN = ROW_NUMBER() OVER (ORDER BY RecCnt DESC)
    FROM Data
)
,CTE2 AS (
    SELECT *, 
        RN2 = ROW_NUMBER() OVER(ORDER BY CEILING( RN / @GroupCount * 1.0 ), (( 1 - CEILING( RN / @GroupCount * 1.0 )) * RecCnt ) DESC ) 
    FROM CTE 
)
SELECT 
    CTE2.Entity_ID, 
    CTE2.RecCnt, 
    ((RN2+1) % @GroupCount) +1 GroupIndex, 
    SUM(CTE2.RecCnt) OVER (PARTITION BY ((RN2+1) % @GroupCount)) CmlTotal 
FROM CTE2