(另开新帖)求一个分组过滤掉重复数据的比较有效率SQL的写法

livan1038 2010-10-15 11:11:25
表A:
source_code name update_date remark
----------- ---- ----------- ------
A1 name1 null test1
B1 name1 null test2

表B:
source_code name update_date remark
----------- ---- ----------- ------
A1 name1 2010-10-15 test3


我想把A表和B表的内容用union的方式查询出来,过滤source_code和name有重复的结果,
只取日期最新的那一条记录,得到的结果如下所示:
source_code name update_date remark
----------- ---- ----------- ------
A1 name1 2010-10-15 test3
B1 name1 null test2

大家有没有好一点的写法
这个帖和http://topic.csdn.net/u/20101015/10/377bf0ba-26f0-4289-80aa-c7fa488c18a2.html?1490877597这个帖有一点不同
...全文
168 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
daishaodong 2010-10-15
  • 打赏
  • 举报
回复
13楼这个写法,要sql2005才支持吧
viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sqlcenter 的回复:]
再试试这种,我觉得应该是比较快的了,再觉得慢就没辙了。


SQL code
--> 测试数据:#a
if object_id('tempdb.dbo.#a') is not null drop table #a
create table #a(source_code varchar(8), name varchar(8), update_date datetime, remark v……
[/Quote]

SQLCenter 2010-10-15
  • 打赏
  • 举报
回复
再试试这种,我觉得应该是比较快的了,再觉得慢就没辙了。

--> 测试数据:#a
if object_id('tempdb.dbo.#a') is not null drop table #a
create table #a(source_code varchar(8), name varchar(8), update_date datetime, remark varchar(8))
insert into #a
select 'A1', 'name1', null, 'test1' union all
select 'B1', 'name1', null, 'test2'
--> 测试数据:#b
if object_id('tempdb.dbo.#b') is not null drop table #b
create table #b(source_code varchar(8), name varchar(8), update_date datetime, remark varchar(8))
insert into #b
select 'A1', 'name1', '2010-10-15', 'test3'

;with cte as
(
select id=row_number()over(partition by source_code,name order by update_date desc), *
from (select * from #a union all select * from #b) t
)
select * from cte where id = 1

/*
id source_code name update_date remark
-------------------- ----------- -------- ----------------------- --------
1 A1 name1 2010-10-15 00:00:00.000 test3
1 B1 name1 NULL test2
*/
livan1038 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 fpzgm 的回复:]
引用 10 楼 livan1038 的回复:
引用 4 楼 viqn7qdnt 的回复:
SQL code

--直接+一列试试
select source_code,name,max(update_date) update_date,remark
from (select * from A
union all
select * from B) aa
group by sourc……
[/Quote]

6#的方法我有试过了,效能好像不大行,执行时间太久了
fpzgm 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 livan1038 的回复:]
引用 4 楼 viqn7qdnt 的回复:
SQL code

--直接+一列试试
select source_code,name,max(update_date) update_date,remark
from (select * from A
union all
select * from B) aa
group by source_code,name,remark

这种……
[/Quote]

见#6,看清楚
livan1038 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 viqn7qdnt 的回复:]
SQL code

--直接+一列试试
select source_code,name,max(update_date) update_date,remark
from (select * from A
union all
select * from B) aa
group by source_code,name,remark
[/Quote]
这种情况也是无法过滤的
fpzgm 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 livan1038 的回复:]
引用 2 楼 fpzgm 的回复:
SQL code

with cte as
(select * from A
union all
select * from B)

--方法一
select source_code,name,max(update_date) update_date,remark
from cte group by source_code,name,rema……
[/Quote]

不是,看清楚,如果只是按照source_code name update_date 这三个字段过滤的话,条件里面只需要这三个字段,remark等其他字段忽略,不用写,否则过滤不了
livan1038 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fpzgm 的回复:]
SQL code

with cte as
(select * from A
union all
select * from B)

--方法一
select source_code,name,max(update_date) update_date,remark
from cte group by source_code,name,remark

--方法二
sele……
[/Quote]

谢谢fpzgm ,
这只是一个小例子,我的字段个数有50多个,按照这种where source_code=t.source_code and name=t.name and remark=t.remark条件的写法我就要晕。
fpzgm 2010-10-15
  • 打赏
  • 举报
回复
见#6,#2方法一不能过滤
fpzgm 2010-10-15
  • 打赏
  • 举报
回复

--更正
with cte as
(select * from A
union all
select * from B)

--方法一
select *from cte t
where not exists
(select 1 from cte where source_code=t.source_code and name=t.name and update_date
>t.update_date )

--方法二
select *from cte t
where update_date=(select max(update_date) from cte where source_code=t.source_code and name=t.name )

viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复
嗯。。。2L详细
viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复

--直接+一列试试
select source_code,name,max(update_date) update_date,remark
from (select * from A
union all
select * from B) aa
group by source_code,name,remark

livan1038 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 viqn7qdnt 的回复:]
LZ这只是在原帖那基础上加了一列?
[/Quote]

是的,加了一列,结果过滤不出来了。
fpzgm 2010-10-15
  • 打赏
  • 举报
回复

with cte as
(select * from A
union all
select * from B)

--方法一
select source_code,name,max(update_date) update_date,remark
from cte group by source_code,name,remark

--方法二
select *from cte t
where not exists
(select 1 from cte where source_code=t.source_code and name=t.name and remark=t.remark and update_date
>t.update_date )

--方法三
select *from cte t
where update_date=(select max(update_date) from cte where source_code=t.source_code and name=t.name and remark=t.remark)
viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复
LZ这只是在原帖那基础上加了一列?
viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 fpzgm 的回复:]
#16是错的,试试这种,再不行就没法了

SQL code

--> 测试数据:#a
if object_id('tempdb.dbo.#a') is not null drop table #a
create table #a(source_code varchar(8), name varchar(8), update_date datetime, remark varch……
[/Quote]

我哪里错了?大哥,不合LZ要求就不合LZ要求,干嘛要说错的,至少我运行结果没问题,哪里错了,还请大哥你指教
fpzgm 2010-10-15
  • 打赏
  • 举报
回复
#16是错的,试试这种,再不行就没法了

--> 测试数据:#a
if object_id('tempdb.dbo.#a') is not null drop table #a
create table #a(source_code varchar(8), name varchar(8), update_date datetime, remark varchar(8))
insert into #a
select 'A1', 'name1', null, 'test1' union all
select 'B1', 'name1', null, 'test2'
--> 测试数据:#b
if object_id('tempdb.dbo.#b') is not null drop table #b
create table #b(source_code varchar(8), name varchar(8), update_date datetime, remark varchar(8))
insert into #b
select 'A1', 'name1', '2010-10-15', 'test3'


with cte as (select * from #a union all select * from #b)
select a.source_code,b.name,a.update_date,b.remark
from (select source_code,max(update_date) as update_date from cte group by source_code) a,cte b
where a.source_code=b.source_code and isnull(a.update_date,1)=isnull(b.update_date,1)


/*
source_code name update_date remark
----------- -------- ----------------------- --------
A1 name1 2010-10-15 00:00:00.000 test3
B1 name1 NULL test2
*/


--去掉isnull,就没有update_date为NULL的记录
with cte as (select * from #a union all select * from #b)
select a.source_code,b.name,a.update_date,b.remark
from (select source_code,max(update_date) as update_date from cte group by source_code) a,cte b
where a.source_code=b.source_code and a.update_date=b.update_date

/*
source_code name update_date remark
----------- -------- ----------------------- --------
A1 name1 2010-10-15 00:00:00.000 test3

*/
viqn7qdnt 2010-10-15
  • 打赏
  • 举报
回复

select * into #tt
from (select * from tA
union all
select * from tB) aa

select source_code,max(update_date),name,max(remark) from #tt group by source_code,name

--结果:
/*
source_code update_date name remark
------------- ---------------- --------------- -------------------
A1 2010-10-15 name1 test3
B1 NULL name1 test2
*/

34,590

社区成员

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

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