declare @str varchar(max)
set @str=''
--错误思路:把表的查询错误理解为程序中循环或遍历过程,把where条件理解为循环判定条件
select @str = @str + belong_dept + ';'
from t_b_personnel_default_config
where belong_dept is not null and CHARINDEX(belong_dept,@str) = 0
select @str
select len(@str)
/*运行结果
DG104000;DG139000;DG139000;DG139000;
由结果可以看到:并没有去掉重复的项
原因:select 查询会先根据where条件筛选出满足条件的结果集,然后再对结果集进行select查询,执行某些表达式。
一开始@str为空,CHARINDEX(belong_dept,@str) = 0 显然成立,所以这个表达式并没有起到作用
*/
set @str=''
--正确思路:在select查询中对结果进行判定筛选
select @str = @str + ( case when CHARINDEX(belong_dept,@str)= 0 then convert(varchar(12),belong_dept) + ';' else '' end)
from t_b_personnel_default_config
where belong_dept is not null
select @str
select len(@str)
/*运行结果:
DG104000;DG139000;DG105000;DG148000;DG147000;DG106000;
*/
感谢大家都该博文的关注和评论。
大家提到了效率问题,并且提供了另外一种解决方法
我也特地查看了下SQL的执行计划,如图:
查询一为网友提供的方法的执行计划,查询二为博文中提到的查询
由执行计划,可以看到查询一时间消耗主要在 哈希匹配,即执行distinct 带来
而查询二 使用charindex 带来的工作量很小,主要是聚集索引
查询一与查询二开销之比为 73:27
所以我斗胆认为查询二应该效率比较高,O(∩_∩)O
当然 由于数据量的原因,查询时间均不足1秒,无从考证
再次感谢大家的回复和指教
这样执行没问题,查询效率方面是否再优化下
不错的思路,使用派生表查询可不可以呢?
例如:
declare @str varchar(100);
set @str = '';
select @str = @str + m.dept +'';'
from
(
select distinct belong_dept as dept
from t_b_personnel_default_config
where belong_dept is not null
) as m
select @str