简体   繁体   English

SQL Server中的子字符串有问题

[英]Having issue with substring in SQL Server

I have to split the resolution something like below: 我必须将分辨率拆分如下:

declare @t table (resolution nvarchar(100))

Insert into @t values ('1366 X 768 @ 60 Hz'),
('1024 X 768 @ 60 Hz'),
('640 X 480 @ 70 Hz')

I want the output as 我希望输出为

Fst   |  Snd  | Thd  
------+-------+-----------
1366  |  768  |  60 Hz  
1024  |  768  |  60 Hz  
640   |  480  |  70 HZ

I have tried this query 我已经试过这个查询

select 
    *,
    substring(resolution, 1, charindex('X', resolution) - 1) as fst,
    substring(resolution, charindex('X', resolution) + 1, charindex('@', resolution) + 1) as snd
from 
    @t

But it is not returning the correct output. 但是它没有返回正确的输出。

Can anyone please show me what is wrong in here? 谁能告诉我这里有什么问题吗?

You can also try PARSENAME() function if there are only 3 part every time, and data format always as you shown. 如果每次只有3个部分,您也可以尝试PARSENAME()函数,并且数据格式始终如您所显示。

SELECT 
PARSENAME(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.') ,3) Fst,
PARSENAME(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.') ,2) Snd,
PARSENAME(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.') ,1) Thd
FROM @t

Output is- 输出是-

Fst     Snd     Thd
1366    768     60 Hz
1024    768     60 Hz
640     480     70 Hz

If you wants to exlude ' Hz' from the Thd column, Just do it- 如果要从Thd列中排除“ Hz”,只需执行以下操作-

SELECT 
PARSENAME(REPLACE(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.'),' Hz','') ,3) Fst,
PARSENAME(REPLACE(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.'),' Hz','')  ,2) Snd,
PARSENAME(REPLACE(REPLACE(REPLACE(resolution,' X ','.'),' @ ','.'),' Hz','')  ,1) Thd
FROM @t

Here you go 干得好

declare @t table (resolution nvarchar(100))

Insert into @t values ('1366 X 768 @ 60 Hz'),
('1024 X 768 @ 60 Hz'),
('640 X 480 @ 70 Hz');

SELECT LEFT(Resolution, CHARINDEX('X', Resolution) - 1) [1St],
       SUBSTRING(Resolution, CHARINDEX('X', Resolution)+1, CHARINDEX('@', Resolution)-
       CHARINDEX('X', Resolution)-2) [2nd],
       SUBSTRING(Resolution, CHARINDEX('@', Resolution)+1, CHARINDEX('H', Resolution)-
       CHARINDEX('@', Resolution)-2) [3rd]
FROM @t;

Online demo 在线演示

Or more better(without white spaces) 或更佳(无空格)

SELECT LEFT(Resolution, CHARINDEX('X', Resolution) - 2) [1St],
       SUBSTRING(Resolution, 
                 CHARINDEX('X', Resolution)+2, 
                 CHARINDEX('@', Resolution)- CHARINDEX('X', Resolution)-3
                ) [2nd],
       SUBSTRING(Resolution, 
                 CHARINDEX('@', Resolution)+2, 
                 CHARINDEX('H', Resolution) - CHARINDEX('@', Resolution)-3
                ) [3rd]
FROM @t

If you want 'Hz' to be in the third column then 如果您希望'Hz'位于第三列,则

SELECT LEFT(Resolution, CHARINDEX('X', Resolution) - 2) [1St],
       SUBSTRING(Resolution, 
                 CHARINDEX('X', Resolution)+2, 
                 CHARINDEX('@', Resolution)- CHARINDEX('X', Resolution)-3
                ) [2nd],
       SUBSTRING(Resolution, 
                 CHARINDEX('@', Resolution)+2, 
                 LEN(Resolution)
                ) [3rd]
FROM @t;

Also, you could use PARSENMAE() function (as mkrabbani provide)to return both results as the following: 另外,您可以使用PARSENMAE()函数(如mkrabbani提供)返回以下两个结果:

  • With 'Hz' 带有'Hz'

     SELECT Resolution, PARSENAME(Res, 3) Fst, PARSENAME(Res, 2) Snd, PARSENAME(Res, 1) Thd FROM ( VALUES ('1366 X 768 @ 60 Hz'), ('1024 X 768 @ 60 Hz'), ('640 X 480 @ 70 Hz') ) T(Resolution) CROSS APPLY ( SELECT REPLACE(REPLACE(T.Resolution, ' X ', '.'), ' @ ', '.') Res ) TT; 
  • Without 'Hz' : 没有'Hz'

     SELECT Resolution, PARSENAME(Res, 3) Fst, PARSENAME(Res, 2) Snd, PARSENAME(Res, 1) Thd FROM ( VALUES ('1366 X 768 @ 60 Hz'), ('1024 X 768 @ 60 Hz'), ('640 X 480 @ 70 Hz') ) T(Resolution) CROSS APPLY ( SELECT REPLACE(REPLACE(REPLACE(T.Resolution, ' X ', '.'), ' @ ', '.'), 'Hz', '') Res ) TT; 

Demo for the last 3 queries. 最后3个查询的演示

You can use this : 您可以使用:

select 
    *,
    substring(resolution, 1, charindex('X', resolution) - 1) as fst,
    substring(resolution, charindex('X', resolution) + 1, charindex('@', resolution) - charindex('X', resolution)-1) as snd ,
    substring(resolution, charindex('@', resolution) + 1,len(resolution) -  charindex('@', resolution)  ) as thr
from 
    @t

A bit cleaner code using APPLY 使用APPLY的代码更简洁

SELECT LEFT(Resolution, idx1 - 2) [1St],
       SUBSTRING(Resolution, idx1 + 2, idx2 - idx1 - 3) [2nd],
       SUBSTRING(Resolution, idx2 + 2, CHARINDEX('H', Resolution) - idx2 - 3) [3rd]
FROM @t
CROSS APPLY (
     SELECT CHARINDEX('X', Resolution) idx1
          , CHARINDEX('@', Resolution) idx2) i 

You can use PARSENAME function to split : 您可以使用PARSENAME函数进行拆分:

SELECT *,
    PARSENAME(REPLACE(PARSENAME(REPLACE(resolution,'@','.'),2),'X','.'),2) 'Fst' ,
    PARSENAME(REPLACE(PARSENAME(REPLACE(resolution,'@','.'),2),'X','.'),1) 'Snd' ,
    PARSENAME(REPLACE(resolution,'@','.'),1) 'Thd'
FROM @t 

And since no string parsing post would be complete without an XML based solution: 而且,如果没有基于XML的解决方案,没有任何字符串解析文章将是完整的:

SELECT ResXml.value(N'/x[1]', 'nvarchar(100)') As Fst,  
       ResXml.value(N'/x[2]', 'nvarchar(100)') As Snd, 
       ResXml.value(N'/x[3]', 'nvarchar(100)') As Thd
FROM
(
    SELECT CAST('<x>'+ REPLACE(REPLACE(resolution, ' X ', '</x><x>'), ' @ ', '</x><x>') + '</x>' As Xml) As ResXml
    FROM @t
) As x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM