sql server中将一个字段根据某个字符拆分成多个字段显示

摘要:
sqlserver数据库中的一个表的数据信息是:IDAddress1平山花园-第四单元-12号楼-2032香山花园-第三单元-22号楼-304现在需要将地址信息显示形式更改为四列,即小区名称、小区号和楼号,房间号分为四列来显示小区列表的ID,建筑物编号、房间编号、房间数量、房间编号,房间的号码,房间的号码。对象_名称的数据类型为sysname。PARSENAME仅返回指定对象名称的指定部分。

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 Person

PS:还有一种更加粗暴的写法  就是不用另外创建函数 直接select 的时候  就通过截取字符串,来附加新的列

例如:有一个需求是 T_Person表中有字段Birth  里面的信息在输入的时候  形式不符合规定

IDBirth
11900/2/12
21898/2/3
3 
4NULL

现在要求统一形式成: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
复制代码

执行之后的结果是:

IDBirth
11900-02-12
21898-02-03
3 
4NULL
 
 

免责声明:文章转载自《sql server中将一个字段根据某个字符拆分成多个字段显示》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WMI获取驱动版本shell遍历文件目录,监听文件变化,拼接字符串下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python基础之字符编码

一 了解字符编码的知识储备 1. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失 因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。 在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,...

Unity 3D 的四种坐标系

1, World Space(世界坐标): 我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。 2, Screen Space(屏幕坐标): 以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位...

Linux系统下常用快捷键

Linux常用快捷键 Linux系统中快捷键的使用会使我们的工作更加简洁高效,常常能够达到事半功倍的效果,如下简单的介绍一些在工作中最为常用快捷键: tab 补全命令或路径 (ctrl+i也可) ctrl+? 撤消前一次输入 ctrl+c 终止当前命令或程序/另起一行(换行) ctrl+l 清屏相当于clear命令 ctrl+d 删除光标所在位置上的字符(...

Base64和urlencode

https://www.jianshu.com/p/b611e220ef2d Base64 使用base64的初衷。是为了方便把含有不可见字符串的信息用可见字符串表示出来 我们知道在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。 而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的...

linux下使用find xargs grep查找文件及文件内容

1,在某个路径下查文件。 在/etc下查找“*.log”的文件 find /etc -name “*.log” 2,扩展,列出某个路径下所有文件,包括子目录。 find /etc -name “*” 3,在某个路径下查找所有包含“hello abcserver”字符串的文件。 find /etc -name “*” | xargs grep “...

Python基础24_正则表达式,re模块,

 一. 正则表达式     正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。     正则表达式由普通字符和元字符组成, 普通字符包含大小写字母, 数字. 在匹配普通字符的时候我们直接写就可以了  ...