【问题标题】:SQL Server: Partition table into multiple tablesSQL Server:将表分区为多个表
【发布时间】:2019-08-08 14:47:36
【问题描述】:

我们可以使用分区根据一个键(多个列值)将表拆分为多个表吗?

结果集: 我的存储过程中有一个临时表#results

ConId  ActNbr StageId  Qty   HoursInStage HoursPassed HourlyQty FlowedQty
------ ------ ------- ------ ------------ ----------- --------- ---------
6814     77     1     24000      24           0           NULL     NULL
6814     77     2     36000      19           5           NULL     NULL
6814     77     3     48000      15           9           NULL     NULL
6814     77     4     60000      11           13          NULL     NULL
6814     77     6     60000      24           0           NULL     NULL
6855     33     1     0          24           0           NULL     NULL
6855     33     2     15000      19           5           NULL     NULL
6855     33     3     15000      15           9           NULL     NULL
6855     33     4     15000      11           13          NULL     NULL
6855     33     6     20000      24           0           NULL     NULL
176892   10     1     0          24           0           NULL     NULL
176892   10     2     0          19           5           NULL     NULL
176892   10     3     0          15           9           NULL     NULL
176892   10     4     0          11           13          NULL     NULL
176892   10     6     0          24           0           NULL     NULL
176892   47     1     0          24           0           NULL     NULL
176892   47     2     0          19           5           NULL     NULL
176892   47     3     0          15           9           NULL     NULL
176892   47     4     0          11           13          NULL     NULL
176892   47     6     0          24           0           NULL     NULL

想要对具有相同ConIdActNbr 的公共行进行分区。并将结果行插入到一个新的临时表中。

ConId  ActNbr StageId  Qty   HoursInStage HoursPassed HourlyQty  FlowedQty
------ ------ ------- ------ ------------ ----------- ---------  ---------
6814     77     1     24000      24           0           NULL      NULL
6814     77     2     36000      19           5           NULL      NULL
6814     77     3     48000      15           9           NULL      NULL
6814     77     4     60000      11           13          NULL      NULL
6814     77     6     60000      24           0           NULL      NULL

ConId  ActNbr StageId  Qty   HoursInStage HoursPassed HourlyQty  FlowedQty
------ ------ ------- ------ ------------ ----------- ---------  ---------
6855     33     1     0          24           0           NULL      NULL
6855     33     2     15000      19           5           NULL      NULL
6855     33     3     15000      15           9           NULL      NULL
6855     33     4     15000      11           13          NULL      NULL
6855     33     6     20000      24           0           NULL      NULL

-- splits other rows same as above two tables

我曾尝试使用分区,但最终不成功。不确定我是否朝着正确的方向前进以实现我所需要的。

评论更新: 我的意思是桌子上的分区。拆分 #results 表的原因是为了对单个拆分表执行一些数学运算,这些拆分表会在 24 小时的最终结果集上返回,每一行代表每个小时,并且 qty 列在此分区表上带有一些数学运算。

在搜索和尝试不同的数学/逻辑方法后,我明白在我的案例 java 中进行进一步编码总是更好。

我已经在 java 上使用 HashMap<Key,Value> 解决了这个问题。包含两列(ConIdActNbr)的键对象和具有剩余列的对象列表。

但问题仍然存在,是否可以基于键(由表列形成)拆分表并将此拆分记录用作常规表?

【问题讨论】:

  • 你说的分区是表分区还是windows函数?
  • 你能告诉我们你尝试过的查询吗?
  • 您要创建多个temp table 吗?每个ConId + ActNbr 组合一个temp table
  • 如果我理解正确,您希望获取一个数据集并根据某些列值将其放入多个表中。第一个问题是:为什么?您可能出于不正确的原因这样做。
  • 是的,没错@Squirrel

标签: sql-server


【解决方案1】:

你需要使用带游标的动态sql来实现。

DECLARE @CONID INT
DECLARE @ACTNBR INT
DECLARE DBCUR CURSOR FOR
SELECT DISTINCT ConId,  ActNbr FROM #RESULTS
OPEN DBCUR 
FETCH NEXT FROM DBCUR INTO @CONID, @ANTNBR
WHILE @@FETCH_STATUS = 0
BEGIN

DECLARE @QUERY NVARCHAR(MAX)
SET @QUERY = 'SELECT * INTO #TMP' + CAST(@CONID AS VARCHAR(10)) + '_' + CAST(@ANTNBR AS VARCHAR(10)) + ' 
                FROM (SELECT * FROM YOURTABLE WHERE CONID =' + CAST(@CONID AS VARCHAR(10)) + ' AND ANTNBR =' + CAST(@ANTNBR AS VARCHAR(10)) + ') AS D;  '

EXEC SP_EXECUTESQL @QUERY

SET @QUERY = ' SELECT * FROM #TMP' + CAST(@CONID AS VARCHAR(10)) + '_' + CAST(@ANTNBR AS VARCHAR(10)) + ';   
               DROP TABLE #TMP' + CAST(@CONID AS VARCHAR(10)) + '_' + CAST(@ANTNBR AS VARCHAR(10)) + ''   ---- you may remove this line if want to use these temp table further 

EXEC SP_EXECUTESQL @QUERY


FETCH NEXT FROM DBCUR INTO @CONID, @ACTNBR
END
CLOSE DBCUR
DEALLOCATE DBCUR

【讨论】:

    【解决方案2】:

    你可以同时使用动态查询和游标

    --example data
    SELECT *
    INTO #temp
    FROM (
    SELECT 1 as Col1, 'X' as col2 , 'some other' as col3
    UNION 
    SELECT 1 as Col1, 'X' as col2 , 'some other 2' as col3
    UNION
    SELECT 1 as Col1, 'Y' as col2 , 'some other 3' as col3
    UNION
    SELECT 2 as Col1, 'X' as col2 , 'some other' as col3
    UNION 
    SELECT 2 as Col1, 'X' as col2 , 'some other 2' as col3
    UNION
    SELECT 2 as Col1, 'Y' as col2 , 'some other 3' as col3
    ) A
    
    
    
    -- partitioning into multiple tables
    declare  @table_ext int = 1;
    declare  @col1 varchar(10);
    declare  @col2 varchar(10);
    declare @sql_st nvarchar(100);
    declare cur cursor for select distinct col1 , col2 from #temp
    
    open cur;
    
    fetch next from cur into @col1 , @col2
    while @@FETCH_STATUS = 0
    begin
        set @sql_st = concat('select * into ##temp', @table_ext, ' from #temp' ,' where col1 = ''', @col1 ,'''  and col2 = ''' , @col2,'''')
        exec sp_executesql @sql_st
        fetch next from cur into @col1 , @col2;
        set @table_ext = @table_ext + 1
    end
    close cur;
    deallocate cur;
    
    
    -- test whether data stored correctly
    select * from ##temp1
    select * from ##temp2
    select * from ##temp3
    select * from ##temp4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多