改写优化SQL(5):带top的标量子查询改写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yupeigu/article/details/79148957

带top的标量子查询,是在标量子查询中,加上了top 1,因为如果不加top 1,关联后可能返回超过1条数据,就导致sql报错了。

但是加了top 1,又没有排序,比如:去最早的一条,或者最晚的一条。


这种写法,在语义上有点随意,因为top 1就是随机返回一条,这种写法不是很严谨,从语句的意思上,可以直接改为求max或者min。

更进一步,就发现,这种写法,其实和上篇文章里的标量子查询行专列很像,可以转成left join的写法。


(1)建表

create table t1(id int,name varchar(20))

create table t2(id int,idd int,type varchar(10))


insert into t1
select 1,'a' union all
select 2,'b' union all
select 3,'c'

insert into t2
select 1,1,'0' union all
select 1,2,'1' union all
select 1,3,'1' union all
select 1,4,'2' union all
select 1,5,'2' union all

select 2,1,'0' union all
select 2,2,'1' union all
select 2,3,'1' union all

select 3,1,'0' union all
select 3,1,'1' union all
select 3,1,'2' union all
select 3,1,'2'

(2)原始top 写法

select t1.id,
       t1.name,
	   (select top 1 idd from t2 where t1.id = t2.id and t2.type='0') t0,
	   (select top 1 idd from t2 where t1.id = t2.id and t2.type='1') t1,
       (select top 1 idd from t2 where t1.id = t2.id and t2.type='2') t2
from t1
/*
id	name	t0	t1	t2
1	a	1	2	4
2	b	1	2	NULL
3	c	1	1	1
*/


(3)改成用min函数


select t1.id,
       t1.name,
	   (select min(idd) from t2 where t1.id = t2.id and t2.type='0') t0,
	   (select min(idd) from t2 where t1.id = t2.id and t2.type='1') t1,
       (select min(idd) from t2 where t1.id = t2.id and t2.type='2') t2
from t1
/*
id	name	t0	t1	t2
1	a	1	2	4
2	b	1	2	NULL
3	c	1	1	1
*/


(4)再把用min函数,改成left join


select t1.id,
       t1.name,
	   t2.t0,
	   t2.t1,
	   t2.t2
from t1
left join
(
	  select id,
	         min(case when type='0' then idd end) t0,
			 min(case when type='1' then idd end) t1,
			 min(case when type='2' then idd end) t2
	  from t2
	  group by id

)t2
 on t2.id = t1.id
/*
id	name	t0	t1	t2
1	a	1	2	4
2	b	1	2	NULL
3	c	1	1	1
*/


猜你喜欢

转载自blog.csdn.net/yupeigu/article/details/79148957
今日推荐