• 写在前面

之前做了个微信端顾客扫码评价员工的功能,除了打分数,还可以打标签。

需要统计分数和统计各个员工每种标签被点击的次数。

后来加了个要求,需要查看客户对某个员工一次服务所打出的标签组合。

   在不修改表设计的前提下,解决这个问题!

实际开发时数据表设计需要考虑的东西比较多,而这篇分享主要是写函数的应用,为了方便看,所以表设计简化了,下面两个表的设计也都是简化过的。

   数据表设计如下(只列出部分要用到的字段):

   测试数据格式如下:

         

备注说明:

(1)tagIDs的值1,2,表示“态度非常好,笑容甜美”。

(2)表2的每1条记录代表客户的每1次评价。

所以,问题可以简化为查询表2中id=2的中文标签组合,返回“态度非常好,笑容甜美”。

在解决问题之前,先来认识几个函数!!!

--------@_@! 知识点一 ---------------------------------------------------------------------------

  charindex函数

  charindex函数返回字符或者字符串在另一个字符串中的起始位置。

  charindex函数调用方法如下:CHARINDEX ( expression1 , expression2 [ , start_location ] )

--------------------------------------------------------------------------------------------------

语句示例:

select charindex('', '1,2,3') as position
select charindex('world', 'hello,world') as position
select charindex('sql', 'hello,world') as position

在sqlserver中运行后的结果为:

1
7
0

可见,当experssion1与expression2没有匹配时返回0。

--------@_@??----------------------------------------------------------------------------

  疑问:这样的写法是正确的吗?

  提问:如果tagIDs='1,2,3,16',那么id=6的话,按上面的写法是不是也算是包含在里面?

-----------------------------------------------------------------------------------------

sqlserver中执行下面语句:

select 'found' as flag where charindex(ltrim(6),'1,2,3,16')>0

输出结果为:found

=_=|| 那么该如何处理使得6不会跟16里面的6匹配上呢?

当6变成“,6,”时,“,6,”就不会和“1,2,3,16”中的6匹配上了!

那么“,6,”和“1,6”中的6也匹配不上了!

把母字符串也进行修改也在前后都加上“,”

这样“6”和“,1,6,”、“,6,7,8,”中的6都可以匹配上了!同时也跟“,1,2,3,16,”中16的6匹配不上。

select 'notFound' as flag where charindex(','+ltrim(6)+',',','+'1,2,3,16'+',')=0

查询结果为:notFound。 问题解决~

--------@_@ 知识点二 -----------------------------------------------------------------------

  STUFF ( character_expression , start , length ,character_expression )

  参数说明:

   character_expression :一个字符数据表达式。character_expression 可以是常量、变量,也可以是字符列或二进制数据列。

  start :一个整数值,指定删除和插入的开始位置。如果 start 或 length 为负,则返回空字符串。 如果 start 比第一个character_expression 长,则返回空字符串。start 可以是 bigint 类型。

  length :一个整数,指定要删除的字符数。如果 length 比第一个 character_expression 长,则最多删除到最后一个character_expression 中的最后一个字符。length 可以是 bigint 类型。

  返回类型 :如果 character_expression 是受支持的字符数据类型,则返回字符数据。如果 character_expression 是一个受支持的 binary 数据类型,则返回二进制数据。

 

  备注 :

  如果开始位置或长度值是负数,或者如果开始位置大于第一个字符串的长度,将返回空字符串。

  如果要删除的长度大于第一个字符串的长度,将删除到第一个字符串中的第一个字符。

  如果结果值大于返回类型支持的最大值,则产生错误。

------------------------------------------------------------------------------------------------

语句示例:

select stuff('abcdef', 2,4,'') --将'abcdef'从第2个开始,连续删掉4个字符,然后将'123'插入

 执行结果:

a123f

----------@_@ 知识点三 ----------------------------------------------------------------

  For xml path: 用于将查询结果集以XML形式显示

------------------------------------------------------------------------------------------

我们用下面这张表的数据来体验下:

示例语句:

select id, tagName from tb_tagList for xml path  

执行结果:

<row>
<id>1</id>
<tagName>态度非常好</tagName>
</row>
<row>
<id>2</id>
<tagName>笑容甜美</tagName>
</row>
<row>
<id>3</id>
<tagName>效率很高</tagName>
</row>
<row>
<id>5</id>
<tagName>对人热情</tagName>
</row>
<row>
<id>6</id>
<tagName>为他人着想</tagName>
</row>
<row>
<id>7</id>
<tagName>细心负责</tagName>
</row>

如果想改成用“,”,修改语句如下:

SELECT tagName + ',' FROM tb_tagList FOR XML PATH('')

执行结果:

态度非常好,笑容甜美,效率很高,对人热情,为他人着想,细心负责,

会发现最后面还有个逗号!

如果想把它去掉,可以修改语句,将逗号加在每个标签的前面,然后stuff函数把第一个逗号替换为空字符串。

将 tagName + ',' 改为  ',' + tagName 

修改语句

SELECT tagNames = (stuff (( select ','+tagName  FROM tb_IntegralTagList where fk_scoreCriterion_id = 1 FOR XML PATH('')),1,1,''))

执行结果:

态度非常好,笑容甜美,效率很高,对人热情,为他人着想,细心负责

接下来开始解决问题!!!

比如,查看表2中id=6的评价标签,输出结果为“态度非常好,笑容甜美”

      

解决方案如下:

(1)先把客户评价表中的标签序列对应的标签查出来

(2)再将tagName进行拼接,变成下面这样

开始实践!!!

由于之前写过这样的查询语句“select * from tabel where id in (1,2,3,4)”,所以想都没想,直接将前端传入的tagIDs = "1,2,3"直接查询。

(-_-)|||  智障~居然犯这种低级错误~

继续解决上面的问题,利用charindex,把id转成字符,看是否包含于tagIDs里面

(1)首先去tagIDs里id对应的标签值

select a.tagName, b.id as appraisalId from tb_tagList a, tb_customerAppraisal b
where charindex(','+ltrim(a.id)+',',','+b.tagIDs+',')>0

运行结果:

(2)将相同appraisalId的标签进行拼接,语句整理如下:

select b.id as appraisalId,a.tagName into #temp  from tb_tagList a, tb_customerAppraisal b
where charindex(','+ltrim(a.id)+',',','+b.tagIDs+',')>0 select appraisalId, tagNames = (stuff((select ',' + tagName from #temp where appraisalId = c.appraisalId for xml path('')),1,1,''))
from #temp c group by c.appraisalId drop table #temp

执行结果:(这里将每一次评价的标签都进行拼接,如有需要可以进行进一步地细节处理 )

@_@)Y 分享到此结束~

sqlserver -- 学习笔记(八)体验charindex、stuff 和 for xml path在实际问题中的应用及几个问题的探讨的更多相关文章

  1. SQLServer学习笔记系列2

    一.写在前面的话 继上一次SQLServer学习笔记系列1http://www.cnblogs.com/liupeng61624/p/4354983.html以后,继续学习Sqlserver,一步一步 ...

  2. SQLServer学习笔记系列6

    一.写在前面的话 时间是我们每个人都特别熟悉的,但是到底它是什么,用什么来衡量,可能很多人会愣在那里.时间可以见证一切,也可以消磨一切,那些过往的点点滴滴可思可忆.回想往年清明节过后,在家乡的晚上总能 ...

  3. SQLServer学习笔记系列5

    一.写在前面的话 转眼又是一年清明节,话说“清明时节雨纷纷”,武汉的天气伴随着这个清明节下了一场暴雨,整个城市如海一样,朋友圈渗透着清明节武汉看海的节奏.今年又没有回老家祭祖,但是心里依然是怀念着那些 ...

  4. SQLServer学习笔记系列3

    一.写在前面的话 今天又是双休啦!生活依然再继续,当你停下来的时候,或许会突然显得不自在.有时候,看到一种东西,你会发现原来在这个社会上,优秀的人很多,默默 吃苦努力奋斗的人也多!星期五早上按时上班, ...

  5. SQLServer学习笔记<>相关子查询及复杂查询

    二.查询缺少值的查询 在这里我们加入要查询2008年每一天的订单有多少?首先我们可以查询下订单表的订单日期在2008年的所有订单信息. 1 select distinct orderdate,coun ...

  6. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  7. SQLServer 学习笔记之超详细基础SQL语句 Part 12(The End)

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 11------------------- 现在,我们希望从 " ...

  8. SQLServer 学习笔记之超详细基础SQL语句 Part 11

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 10------------------- DECLARE @myavg ...

  9. SQLServer 学习笔记之超详细基础SQL语句 Part 10

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 9------------------- 删除约束的语法 ALTER T ...

随机推荐

  1. 使用knockout-sortable实现对自定义菜单的拖拽排序

    在开始之前,照例,我们先看效果和功能实现. 关于自定义菜单的实现,这里就不多说了,需要了解的请访问:http://www.cnblogs.com/codelove/p/4838766.html 这里需 ...

  2. ListView用法总结

    前言 列表,它作为一种非常重要的显示形式,不管是在web端还是在移动平台上,都是一种非常友好的,功能强大的展现形式.在Android中,ListView就接管了这一重任.尽管在Android5.X时代 ...

  3. 图解集合3:CopyOnWriteArrayList

    初识CopyOnWriteArrayList 第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Driver都是维护在一个CopyOnWriteArrayLis ...

  4. clearTimeout消除闪动

    需求:当鼠标放到父级菜单上面的时候,显示下方的子菜单.鼠标从子菜单或者父级菜单上面移开的时候,子菜单要收起来.最终效果如下: PS:这样需求很常见,最常见的做法是li元素下面再嵌套一个Ul元素来包含子 ...

  5. Javascript事件模型系列(一)事件及事件的三种模型

    一.开篇 在学习javascript之初,就在网上看过不少介绍javascript事件的文章,毕竟是js基础中的基础,文章零零散散有不少,但遗憾的是没有看到比较全面的系列文章.犹记得去年这个时候,参加 ...

  6. XP之后Windows的一些变化

    看到很多Windows开发人员,尤其是C++程序员思维还是停留在XP操作系统,当然根据工作是否需要新知识 ,这本身没有错.但是实际上Vista之后的Win7, 再之后的Win8 ,Windows已经发 ...

  7. 常用CSS优化总结——网络性能与语法性能建议

    在前端面试中最常见的问题就是页面优化和缓存(貌似也是页面优化),被问了几次后心虚的不行,平然平时多少会用到一些,但突然问我,很难把自己知道的都说出来.页面优化明显不是一两句能够说完的,这两天总结了一下 ...

  8. 一则线上MySql连接异常的排查过程

    Mysql作为一个常用数据库,在互联网系统应用很多.有些故障是其自身的bug,有些则不是,这里以前段时间遇到的问题举例. 问题 当时遇到的症状是这样的,我们的应用在线上测试环境,JMeter测试过程中 ...

  9. NSDate NSString相互转化

    时间戳是经常用到的,今天就总结一下 //设置转化格式 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter s ...

  10. EF架构~数据分批批量提交

    回到目录 对于大数据量提交,包括插入,更新和删除,我始终不建议用EF自带的方法,因为它会增加与数据库的交互次数,一般地,EF的一个上下文在提交时会打开一个数据连接,然后把转换成的SQL语句一条一条的发 ...