日期:2014-05-18  浏览次数:20447 次

如何通过代码将SqlServer多个表格的数据合并到一个表格并且删除相同的行 谢谢
如何通过代码将SqlServer多个表格的数据合并到一个表格并且删除相同的行 谢谢

每天生成一个数据表格,为了实现查询功能,现在想通过代码实现自动将现有的所有表格全部都汇总到一个表格中,并且删除其中重复的行。请指教

------解决方案--------------------
SQL code

insert tb
select * from(
select * from tb1
union
select * from tb2
union
select * from tb3
)t
--删除重复行:
delete a from tb a where exists (select 1 from tb b where a.col=b.col and a.id<b.id)

------解决方案--------------------
TravyLee确实实战经验丰富啊,赞一个。
但是个人感觉先插入,再删除的做法,在效率上稍欠,无论是sql server还是oracle,都提供了merge的语法,使用系统自带的东西,个人感觉总比自己操作要好。
嗯,还有点小毛病是最终合并出来的表,如果采用自动增长列,删除数据后,编号无法保证连续。当然,对用没有任何影响,只是对于某些偏执狂而言。

下面提供了段代码,用了游标,个人是不喜欢用游标的,影响效率,但对于这种数据量不大的表,倒也不是太大的问题。

如果说到有更好的解决办法,我觉得是不用存储过程,直接使用osql生成sql脚本,原理和上面TravyLee所说的类似(oracle中常用的手法)。
然后再在调度中,每月定时执行,可能会更好些。

该吃饭了,去晚了就没了,脚本的办法一会再说。

以上,如果说得不对,请各位指正。

SQL code

--测试数据,待合并表;
create table a_s1(
id int
);
go

create table a_s2(
id int
);
go

create table a_s3(
id int
);
go

--测试数据;
insert a_s1
select 1 union all
select 2;
go

insert a_s2
select 2 union all
select 3;
go

insert a_s3
select 3 union all
select 4 union all
select 5
go

select * from a_s1;
select * from a_s2;
select * from a_s3;

--临时表,合并数据至此表;
create table #tt
(
id int identity(1,1),
value int
)
go

select * from #tt;


--开始创建存储过程;
if OBJECT_ID('pro_test') is not null
begin
    drop proc pro_test;
end;
go

--创建存储过程;
CREATE PROC pro_test
AS
BEGIN
    --声明变量,存放待执行动态sql语句;
    DECLARE  @sql varchar(max);
    --声明变量,用于存放表名;
    DECLARE  @tableName varchar(max);
    --声明游标,用于读取表名;
    DECLARE myCursor CURSOR FOR
    SELECT name
    FROM sysobjects
    WHERE xtype='U' and category=0 
    and CHARINDEX('a_',name)=1;    
    
    --打开游标
    OPEN myCursor;
    --开始读取;
    FETCH NEXT FROM myCursor
    INTO @tableName;
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --PRINT @tableName;
        --动态创建sql语句;        
        set @sql = 'MERGE INTO #tt AS t ' +
            ' using (select id from ' + @tableName + ') as s ' +
            ' on t.id = s.id ' +
            ' when not matched then ' +
            '    insert (value) values  (id);';    
        --print @sql;
        
        --执行;
        exec(@sql);
        FETCH NEXT FROM myCursor
        INTO @tableName;
    END;
        
    --关闭游标;
    CLOSE myCursor;
    DEALLOCATE myCursor;
END;


pro_test;


--查看数据
select * from #tt;