Sql server 将SQL表拆分为子表

Sql server 将SQL表拆分为子表,sql-server,tsql,Sql Server,Tsql,我有一个庞大的数据表,需要以某种方式进行聚合。数据太大,无法一次完成,因此我首先将表拆分为N个子表,并在单独的块上执行聚合。执行拆分的代码(在下面的情况下拆分为3个单独的子表)为 创建我使用的第二个子表 SELECT [EpiSer], [SINum], [VolNum], [CTPQty], [VolAmt], [CTPActivityGroupCode] INTO [_Stage2_Part2] FROM [

我有一个庞大的数据表,需要以某种方式进行聚合。数据太大,无法一次完成,因此我首先将表拆分为N个子表,并在单独的块上执行聚合。执行拆分的代码(在下面的情况下拆分为3个单独的子表)为

创建我使用的第二个子表

SELECT [EpiSer], 
       [SINum], 
       [VolNum], 
       [CTPQty], 
       [VolAmt], 
       [CTPActivityGroupCode] 
INTO [_Stage2_Part2] 
FROM [_Stage2] 
WHERE [TilingIdx] = 2; -- This number is changed for each split 1, 2 and 3
GO
问题是我在
[epier]
上生成的每个子表组上使用的聚合查询(其中有重复项)。因此,通过这种方式拆分,可以将具有相同
[epier]
的记录拆分为不同的子表,因此当我执行聚合时,我们会丢失一些记录。作为参考,[子表2的]聚合查询为

SELECT [s1].[EpiSer] as ActivityRecordID, 
       [s1].[CTPActivityGroupCode] as ActCstID, 
       [t].[ResCstID], 
       [s1].[VolAmt], 
       [s1].[CTPQty] AS ActCnt, 
       SUM([s1].[VolAmt] * [t].[OCostUnit]) AS TotOCst, 
       SUM([s1].[VolAmt] * [t].[FCostUnit]) AS TotFCst 
INTO [_Agg2] 
FROM [_Stage2_Part2] AS s1 
    INNER JOIN 
        [DriversCtp] AS t ON [s1].[VolNum] = [t].[VolNum] 
GROUP BY [s1].[EpiSer], 
         [s1].[CTPActivityGroupCode], 
         [t].[ResCstID], 
         [s1].[VolAmt], 
         [s1].[CTPQty];
GO
因此,我的问题是,如何将原始表拆分为N个子表,同时确保具有相同
[epier]
的记录保存在相同的子表中


感谢您的时间。

您应该能够在分组后使用另一个
更新来实现这一点。由于您按
ID
订购,我们可以找到每个
ID
的最小组:

DECLARE @DataSource TABLE
(
    [id] TINYINT PRIMARY KEY IDENTITY(1,1)
   ,[value] TINYINT
);

INSERT INTO @DataSource ([value])
VALUES (1), (1), (1), (2), (3), (4), (5), (6), (7), (7), (7), (7), (7), (7), (7), (7), (8), (9), (10), (11);


SELECT *
      ,NTILE(3) OVER(ORDER BY Id)  AS [GroupID]
INTO #DataSource
FROM @DataSource;


SELECT *
      ,MIN([GroupID]) OVER(PARTITION BY [value])
FROM #DataSource

DROP TABLE #DataSource;

我不确定这将如何影响您的性能,但无法确定如何
内联修复分组



此外,如果您使用的是
SQL Server 2012+
,则可以检查-它们可用于跨大型表的聚合。

是的,重做查询优化器的工作很困难。您确定除了亲自物理拆分数据之外,无法进一步优化原始查询吗?我已经在80亿行的表上运行了查询,虽然这肯定需要一段时间(看看如何读取所有数据和所有数据),但它们并不是“太大而无法一次完成”。您是否遇到内存限制?临时表溢出?是的,它是带有聚合的多对多内部联接。拆分是我唯一的选择。拆分之后,我将这些表合并成一个大表。我在想,也许我只需要对最终的联接表进行后期处理,并将聚合查询中按分组的列的具有重复值的记录合并起来——我想这实际上就是我现在要尝试的。感谢您的回复,“拆分是我唯一的选择”。这一点你应该重新考虑。。。当事情以正确的方式进行时,使用大表不是问题。也许你应该尝试在EpiSer上使用稠密的_rank()对大表进行排序,这样你就可以在表上使用ntile()。不确定它是否有用,确定它将花费很长时间…考虑到您正在对s1.VolAmt进行分组,您可以将其从sum中取出(即s1.VolAmt*sum(t.FCostUnit))。通过该更改,您可能能够单独聚合每个表,然后根据聚合结果进行连接。
DECLARE @DataSource TABLE
(
    [id] TINYINT PRIMARY KEY IDENTITY(1,1)
   ,[value] TINYINT
);

INSERT INTO @DataSource ([value])
VALUES (1), (1), (1), (2), (3), (4), (5), (6), (7), (7), (7), (7), (7), (7), (7), (7), (8), (9), (10), (11);


SELECT *
      ,NTILE(3) OVER(ORDER BY Id)  AS [GroupID]
INTO #DataSource
FROM @DataSource;


SELECT *
      ,MIN([GroupID]) OVER(PARTITION BY [value])
FROM #DataSource

DROP TABLE #DataSource;
WITH DataSource AS
(
    SELECT [id]
          ,MIN([GroupID]) OVER(PARTITION BY [value]) AS [GroupID]
    FROM #DataSource
)
UPDATE #DataSource
SET [GroupID] = B.[GroupID]
FROM #DataSource A
INNER JOIN DataSource B
    ON A.[id] = B.[id];