王涛的空间

我们一直在努力....

分享:SQL select 查询的一个小问题

标签: SQLServer Select 查询

SQL中逻辑查询处理的各个阶段执行顺序想必大家都比较清楚了,我也有所了解,但在写SQL语句时,有时还是会忽略掉SQL特有的集合特性。

且看下面这个例子

需求:想要将表中某个字段值以分号拼接起来,并且去掉重复项
备注:此实例只做演示,效率暂且不谈论。当然大家如果有更好的方法,也请多多指教。


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秒,无从考证

再次感谢大家的回复和指教
 


 

    分享: 收藏到CSDN 收藏到javaeye 收藏到博客园 收藏&分享
  • 浏览 (105)
  • 评论 (5)
  • 发表于 2010-11-25 13:59
  • 数据库
    评分: 请先登录再投票,同一篇博客一月只能投票一次!
    无人投票

相关博客:


评论

孙延超 2010-11-26 11:09:32   回复

这样执行没问题,查询效率方面是否再优化下

史玉伦 2010-11-26 16:10:52   回复

不错的思路,使用派生表查询可不可以呢?
例如:
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

史玉伦 2010-11-26 16:11:33   回复

靠,评论完了还不能修改啊

涛声依旧 2010-11-26 17:19:37   回复
呵呵,以后社区会逐渐完善功能和用户体验的!
因为回复不太方便,我又更新了下文章!
欢迎指正~~
Harvey 2010-11-26 17:37:52   回复
支持原创分享

发表评论

关注此文的人们还关注