sql server中将一个字段根据某个字符拆分成多个字段显示
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 的數據類型為 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=1WHILE @index>0BEGINIF @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+1ENDRETURN 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/p/5477385.html
總結
以上是生活随笔為你收集整理的sql server中将一个字段根据某个字符拆分成多个字段显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php pdo操作数据库
- 下一篇: 关于自己