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

wooqr 2012-07-03 09:35:15
如何通过代码将SqlServer多个表格的数据合并到一个表格并且删除相同的行 谢谢

每天生成一个数据表格,为了实现查询功能,现在想通过代码实现自动将现有的所有表格全部都汇总到一个表格中,并且删除其中重复的行。请指教
...全文
4056 39 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
Standy8 2013-05-21
  • 打赏
  • 举报
回复
makeyige yibei houyong
fanluo2005 2012-07-10
  • 打赏
  • 举报
回复
union 语句就可以了
xftmf_2008 2012-07-09
  • 打赏
  • 举报
回复
h 上面给的方法还是不少的 可以看看
quchen520 2012-07-06
  • 打赏
  • 举报
回复
你说的重复记录是怎么定义的?
是某个字段有重复值,还是整条记录都相同才算是重复
wooqr 2012-07-04
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 的回复:]

引用 31 楼 的回复:

数据导入问题基本上已经解决,就是删除重复数据有点问题,因为表格没有设置唯一的关键字id,所以,用如下命令,
delete a from 数据汇总表 a
where exists(select 1 from 数据汇总表 b where a.关键字段=b.关键字段 )

运行结果是所有记录都被删除了,请指教


你这个语句必须的啊。比如说第一行跟第五行……
[/Quote]
谢谢回复,我使用

insert into s_201207 select distinct * from temp_201207

这条命令行吗。temp_201207为一个月所有数据的临时表,s_201207是排除了重复数据的表
wooqr 2012-07-04
  • 打赏
  • 举报
回复
我使用

insert into s_201207 select distinct * from temp_201207

这条命令行吗。temp_201207为一个月所有数据的临时表,s_201207是排除了重复数据的表
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 的回复:]

数据导入问题基本上已经解决,就是删除重复数据有点问题,因为表格没有设置唯一的关键字id,所以,用如下命令,
delete a from 数据汇总表 a
where exists(select 1 from 数据汇总表 b where a.关键字段=b.关键字段 )

运行结果是所有记录都被删除了,请指教
[/Quote]

你这个语句必须的啊。比如说第一行跟第五行重复,你的写出来需要删除行号较大的或者较小的
也就是:
delete a from 数据汇总表 a
where exists(select 1 from 数据汇总表 b where a.关键字段=b.关键字段 and a.行号<b.行号 )
或者
delete a from 数据汇总表 a
where exists(select 1 from 数据汇总表 b where a.关键字段=b.关键字段 and a.行号>b.行号 )

如果表没有行号,那么给表加一个字段:alter table 汇总表 add row_num int identity(1,1)
删除完事后alter table 汇总表 drop column row_num
wooqr 2012-07-04
  • 打赏
  • 举报
回复
数据导入问题基本上已经解决,就是删除重复数据有点问题,因为表格没有设置唯一的关键字id,所以,用如下命令,
delete a from 数据汇总表 a
where exists(select 1 from 数据汇总表 b where a.关键字段=b.关键字段 )

运行结果是所有记录都被删除了,请指教
custom1234 2012-07-04
  • 打赏
  • 举报
回复
ufjiaxy 2012-07-03
  • 打赏
  • 举报
回复
每天一张表 为啥不用分区表呢
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]

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

下面提供了段代码,用了游标,个人是不喜欢……
[/Quote]

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

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

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

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

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


--测试数据,待合并表;
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;

  • 打赏
  • 举报
回复

--给你一个例子:
create table a_s1(
id int
)
go
create table a_s2(
id int
)
go
create table a_s3(
id int
)
insert a_s1
select 1
insert a_s2
select 2
insert a_s3
select 2 union all
select 3
go
create table #tt(
id int identity(1,1),
value int
)
go
if OBJECT_ID('pro_test') is not null
drop proc pro_test
go
create proc pro_test
as
declare @str varchar(max)
set @str=''
select @str=@str+'select * from '+name+CHAR(10)+' union all '+CHAR(10)
from sysobjects
where xtype='U' and category=0
and CHARINDEX('a_',name)=1
select @str=LEFT(@str,LEN(@str)-12)
exec('insert #tt(value) select * from ('+@str+')t')
delete a from #tt a
where exists(select 1 from #tt b where a.value=b.value and a.id<b.id)
go

exec pro_test

select * from #tt
/*
id value
1 1
3 2
4 3
*/

--一个简单的例子
wooqr 2012-07-03
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

引用 14 楼 的回复:

引用 11 楼 的回复:

SQL code
DECLARE @t DATETIME,@s VARCHAR(max),@……


谢谢您的回复,不知道是否能提供实现合并数据和删除相同数据行的完整存储过程代码,非常感谢


都写到这个份上了你还要详细的啊????自己写写嘛
[/Quote]

呵呵,不好意思,让你见笑了,确实比较菜,谢谢回复.
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

引用 11 楼 的回复:

SQL code
DECLARE @t DATETIME,@s VARCHAR(max),@……


谢谢您的回复,不知道是否能提供实现合并数据和删除相同数据行的完整存储过程代码,非常感谢
[/Quote]

都写到这个份上了你还要详细的啊????自己写写嘛
wooqr 2012-07-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

SQL code
DECLARE @t DATETIME,@s VARCHAR(max),@……
[/Quote]

谢谢您的回复,不知道是否能提供实现合并数据和删除相同数据行的完整存储过程代码,非常感谢
wooqr 2012-07-03
  • 打赏
  • 举报
回复
谢谢楼上的回复,请问按照你的代码,最后所有的数据是汇总到了那个表中了呢?
连星入剑端 2012-07-03
  • 打赏
  • 举报
回复
如果楼主是使用的sql2005以上版本,建议在帮助手册里查询下merge的语法,合并么,这种效率是不错的。
筱筱澄 2012-07-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 5 楼 的回复:

一天一个表?你每个表有多少数据?
……

每天每个表大概有100万条数据,所以一个月汇总一次
[/Quote]
才这么点,完全可以把一个月的放一个表,然后月统计之后再放另一个表
之后去统计表查询。

如果设计不能修改那就是拼接了


DECLARE @t DATETIME,@s VARCHAR(max),@i INT,@d INT 
SET @t=GETDATE()--表示取当月的所有表数据
set @d=DATEDIFF(dd,DATEADD(mm,DATEDIFF(mm,0,@t),0),DATEADD(mm,DATEDIFF(mm,0,@t)+1,0))
SET @i=0
WHILE @i<@d
BEGIN
SET @s=ISNULL(@s+'union all'+CHAR(13),'')+'select * from a_'+CONVERT(VARCHAR(8),DATEADD(dd,@i,DATEADD(mm,DATEDIFF(mm,0,@t),0)),112)+CHAR(13)
SET @i=@i+1
END
PRINT @s

/*
select * from a_20120701
union all
select * from a_20120702
union all
select * from a_20120703
union all
select * from a_20120704
union all
select * from a_20120705
union all
select * from a_20120706
union all
select * from a_20120707
union all
select * from a_20120708
union all
select * from a_20120709
union all
select * from a_20120710
union all
select * from a_20120711
union all
select * from a_20120712
union all
select * from a_20120713
union all
select * from a_20120714
union all
select * from a_20120715
union all
select * from a_20120716
union all
select * from a_20120717
union all
select * from a_20120718
union all
select * from a_20120719
union all
select * from a_20120720
union all
select * from a_20120721
union all
select * from a_20120722
union all
select * from a_20120723
union all
select * from a_20120724
union all
select * from a_20120725
union all
select * from a_20120726
union all
select * from a_20120727
union all
select * from a_20120728
union all
select * from a_20120729
union all
select * from a_20120730
union all
select * from a_20120731

*/
  • 打赏
  • 举报
回复

--给你一个例子:
create table a_s1(
id int
)
go
create table a_s2(
id int
)
go
create table a_s3(
id int
)
go
declare @str varchar(max)
set @str=''
select @str=@str+'select * from '+name+CHAR(10)+' union all '+CHAR(10)
from sysobjects
where xtype='U' and category=0
and CHARINDEX('a_',name)=1
select @str=LEFT(@str,LEN(@str)-12)
print @str
/*
select * from a_s1
union all
select * from a_s2
union all
select * from a_s3
*/
加载更多回复(18)

34,836

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧