sqlserver 分列
sql server 数据库中某张表(Person)的数据信息是:
ID |
Address |
1 | 平山花园-4单元-12幢-203 |
2 | 香山花园-3单元-22幢-304 |
现在有需求是,将地址信息显示形式改成4列 ,即小区名,单元号,楼房号,房间号 分成4列进行显示
ID | 小区名 | 单元号 | 楼房号 | 房间号 |
1 | 平山花园 | 4单元 | 12幢 | 203 |
2 | 香山花园 | 3单元 | 22幢 | 304 |
介绍两种方案:
第一种:最简单的办法就是调用sql server中自带函数PARSENAME来进行拆分,但是注意:最多只能拆分成4个字段。
针对这个例子的实现:parsename默认是根据'.'进行拆分的,所以首先要做的是将字段中的‘-’替换成'.'
SELECT Address, PARSENAME(REPLACE([Address],'-','.'),4) as 小区名,
--如果字段的内容是 4单元-12幢-203 那么此时小区名字段的信息就是NULL
PARSENAME(REPLACE([Address],'-','.'),3) as 单元号,
PARSENAME(REPLACE([Address],'-','.'),2) as 楼房号,
PARSENAME(REPLACE([Address],'-','.'),1) as 房间号
FROM Person
PARSENAME详解:
PARSENAME ( 'object_name' , object_piece )
- 'object_name'
-
要检索其指定部分的对象的名称。object_name 的数据类型为 sysname。此参数是可选的限定对象名称。如果对象名称的所有部分都是限定的,则此名称可包含四部分:服务器名称、数据库名称、所有者名称以及对象名称。
- object_piece
-
要返回的对象部分。object_piece 的数据类型为 int 值,可以为下列值:
1 = 对象名称
2 = 架构名称
3 = 数据库名称
4 = 服务器名称
PARSENAME 函数不指示指定名称的对象是否存在。PARSENAME 仅返回指定对象名称的指定部分。
第二种方案:思路:写一个函数 根据特定的分割符号利用SUBSTRING和CHARINDEX将字段进行截取拆分,
--这个函数 返回的是一个表 ALTER FUNCTION [dbo].[f_splitlianxi]
(
@str NVARCHAR(500),--要分割的字符串
@fengefu NVARCHAR(20)--进行分割的符号
)RETURNS @table TABLE(id INT,val NVARCHAR(50))
AS
BEGIN
DECLARE @index INT,@startsplit INT,@id INT --@index分隔符所在的位置的下标 @startsplit 每次分割开始的位置
SELECT @index=CHARINDEX(@fengefu,@str),@startsplit=1,@id=1
WHILE @index>0
BEGIN
IF @id>1 --第一次循环之后 都执行这个方法体中的代码
BEGIN
SELECT @startsplit=@index+LEN(@fengefu) --分割开始位置等于 之前的字符下标位置+字符本身的长度
SELECT @index=CHARINDEX(@fengefu,@str,@startsplit) END
IF @index>0 --第一次循环 截取位置从@startsplit=1开始
BEGIN
INSERT INTO @table VALUES (@id,SUBSTRING(@str,@startsplit,@index-@startsplit)) --要截取的字符串 开始位置 要截取的长度
END
ELSE
BEGIN --最后一次循环 此时由于匹配不到分割字符 @index=0 截取剩余的字符串
INSERT INTO @table VALUES (@id,SUBSTRING(@str,@startsplit,LEN(@str)-@startsplit+1))
END
SELECT @id=@id+1
END
RETURN
END调用规则:
SELECT [Address],(SELECT val FROM [f_splitlianxi]([Address],'-') WHERE id=1 ) AS 小区名 ,
(SELECT val FROM [f_splitlianxi]([Address],'-') WHERE id=2 )AS 单元号,
(SELECT val FROM [f_splitlianxi]([Address],'-') WHERE id=3 )AS 楼房号,
(SELECT val FROM [f_splitlianxi]([Address],'-') WHERE id=4 )AS 房间号
FROM PersonPS:还有一种更加粗暴的写法 就是不用另外创建函数 直接select 的时候 就通过截取字符串,来附加新的列
例如:有一个需求是 T_Person表中有字段Birth 里面的信息在输入的时候 形式不符合规定
ID Birth 1 1900/2/12 2 1898/2/3 3 4 NULL 现在要求统一形式成:1987-05-03的形式:
下面是具体过程:
UPDATE dbo.T_Person SET Birth=
SUBSTRING(Birth,1,CHARINDEX('/',Birth)-1) --得到年份
+'-'+
CASE WHEN SUBSTRING(Birth,CHARINDEX('/',Birth)+1,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)-(CHARINDEX('/',Birth)+1))<10
--截取月份与10进行比较
THEN
'0'+SUBSTRING(Birth,CHARINDEX('/',Birth)+1,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)-(CHARINDEX('/',Birth)+1))
--小于10的时候 在月份前面追加个0 然后返回
ELSE
SUBSTRING(Birth,CHARINDEX('/',Birth)+1,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)-(CHARINDEX('/',Birth)+1))
--大于10的时候 截取月份返回
END
--得到月份
+'-'
+CASE WHEN SUBSTRING(Birth,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)+1,LEN(Birth)-CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1))<10
--截取日与10进行比较
THEN
'0'+SUBSTRING(Birth,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)+1,LEN(Birth)-CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1))
--小于10的时候 在日前面追加个0 然后返回
ELSE
SUBSTRING(Birth,CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1)+1,LEN(Birth)-CHARINDEX('/',Birth,CHARINDEX('/',Birth)+1))
--大于10的时候 截取日返回
END
--得到日
WHERE CHARINDEX('/',Birth)>0 --防止没有/的信息字段 在进行字符串截取的时候报错 没有'/'的返回0 但是NULL 得到的值是NULL --注释
SELECT CHARINDEX('/','123') --结果是 0
SELECT CHARINDEX('/',NULL) --结果是 NULL执行之后的结果是:
ID Birth 1 1900-02-12 2 1898-02-03 3 4 NULL =======================================================================================================================
该文章转自 https://www.cnblogs.com/huangshuqiang/archive/2016/05/10/5477385.html 木头南方
sqlserver 分列的更多相关文章
- SqlServer拆分列
SELECT TOP 1000 substring([a],0,CHARINDEX('/',a)) as low,substring([a],CHARINDEX('/',a)+1,len([a])-C ...
- SQLServer错误代码解释
SQLServer出现错误的代码大全(好用) Code Error Message 0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. ...
- SQLServer导出数据到MySQL
1从SQLServer导出数据 执行BCP: bcp "..." queryout "F:\test.txt" -c –S1.2.3.4 -Usa -P1111 ...
- 01.SQLServer性能优化之----强大的文件组----分盘存储
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...
- 03.SQLServer性能优化之---存储优化系列
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概 述:http://www.cnblogs.com/dunitian/p/60413 ...
- SQLSERVER将一个文件组的数据移动到另一个文件组
SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...
- SQLSERVER走起微信公众帐号已经开通搜狗微信搜索
SQLSERVER走起微信公众帐号已经开通搜狗微信搜索 请打开下面链接 http://weixin.sogou.com/gzh?openid=oIWsFt-hiIb_oYqQHaBMoNwRB2wM ...
- SQLSERVER走起 APP隆重推出
SQLSERVER走起 APP隆重推出 为方便大家查看本微信公众以前推送的文章,QQ群里面的某位SQLSERVER重度爱好者开发了<SQLSERVER走起>的APP 以供大家一起交流 网页 ...
- 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)
分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...
随机推荐
- 如何自制WC3地形纹理贴图
http://world-editor-tutorials.thehelper.net/tilesets.php https://wenku.baidu.com/view/e761c953cc1755 ...
- Unity可编程管线的顶点光照Shader
UnityCG.cginc有一个叫ShadeVertexLightsFull的函数可以用来计算顶点光照. 源码如下: // Used in Vertex pass: Calculates diffus ...
- java中equals与hashCode的重写问题
这几天有一个朋友问我在重写equals和hashCode上出现了问题,最后我帮她解决了问题,同时也整理出来分享给大家 现上Object的equals与HashCode的代码 public boolea ...
- python3之range()
python range() 函数可创建一个整数列表,一般用在 for 循环中. 函数语法(左闭右开) Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以 ...
- softmax交叉熵损失函数求导
来源:https://www.jianshu.com/p/c02a1fbffad6 简单易懂的softmax交叉熵损失函数求导 来写一个softmax求导的推导过程,不仅可以给自己理清思路,还可以造福 ...
- yum管理——ningx部署私有repo源(4)
一.前言: 为了加快安装效率,或者日后服务器处于内网环境,本次特写一片搭建的是一个属于个人私有repo源仓库,思路如下: 1.首先到mirrors.ustc.edu.cn下载用到的源的仓库 2.然后安 ...
- (专题四)06 matlab绘图选项卡
绘图选项卡 例子1--选择已有变量,绘制图形 都是按照选中的先后顺序依次确定坐标, 如果要修改绘制图形 法一,利用绘图工具和停靠图形按钮 法二,命令行窗口中输入命令 >>plottools ...
- Vant IndexBar 在小程序中的简单使用
这篇文章是老王的朋友超超提供的,上午已经更新到原创微信公众号「软件老王」,链接,欢迎各位朋友关注老王的原创公号! 先看下最终效果图,主要是渲染一个A - Z 的 通讯录.同样的,如果你要做的是城市列表 ...
- SpringMVC初始化阶段流程源码分析
1.都知道SpringMVC项目启动的时候都会初始化一个类:DispatcherServlet,看这个类的源码我们可以发现他其实就是一个servlet, 为什么这么说呢?请看: DispatcherS ...
- JVM学习(八)指令重排序
一.数据依赖性 在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性: 编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能[多条指令并行执行,所以提升性能的同时也可能会导致 ...