本示例测试两个表联接查询后,分组并取分组后的最小行号记录
测试表:
tb1表结构如下:
CREATE TABLE [dbo].[tb1]( [a] [nvarchar](50) NOT NULL, [b] [nvarchar](50) NULL, [c] [nvarchar](50) NULL, CONSTRAINT [PK_tb1] PRIMARY KEY CLUSTERED ( [a] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
tb2表结构如下:
CREATE TABLE [dbo].[tb2]( [cc] [nvarchar](50) NOT NULL, [dd] [nvarchar](50) NULL, [bb] [nvarchar](50) NULL, CONSTRAINT [PK_tb2] PRIMARY KEY CLUSTERED ( [cc] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
tb1表内容:
a b c
1 2 adf
2 2 dfd
3 3 测试3
4 3 测试4
tb2表内容:
cc dd bb
1 中国菜 2
2 印度菜 2
3 西餐 3
4 日本料理 3
两个表相关联字段tb1.b=tb2.bb
有两种方法使用SQL可实现:
第一种方法如下:
select * from (select tb1.b,tb1.c,tb2.dd,ROW_NUMBER() over(order by tb1.b) as rowID from tb1 left join tb2 on tb1.b=tb2.bb group by tb1.b,tb1.c,tb2.dd )d --查询行号 where d.rowID in (select minrowID from ( --找最小行号集合 select b,MIN(rowID) as minrowID from --取每个组的最小行号 (select tb1.b,tb1.c,tb2.dd,ROW_NUMBER() over(order by tb1.b) as rowID from tb1 left join tb2 on tb1.b=tb2.bb group by tb1.b,tb1.c,tb2.dd --查询行号 )a group by a.b)c)
执行结果分析信息如下:
第二种方法如下:
select * from (select tb1.b,tb1.c,tb2.dd,ROW_NUMBER() over(order by tb1.b) as rowID from tb1 left join tb2 on tb1.b=tb2.bb group by tb1.b,tb1.c,tb2.dd) t where not exists (select 1 from (select tb1.b,tb1.c,tb2.dd,ROW_NUMBER() over(order by tb1.b) as rowID from tb1 left join tb2 on tb1.b=tb2.bb group by tb1.b,tb1.c,tb2.dd)a where b=t.b and rowID< t.rowID)
执行分析结果如下:
通过两种方式对比,可发现第二种方案执行效率较高,如还有更好的方案,欢迎指教!
执行结果: