sql 字符串值并且仅从管道部分中提取第一个值

发布于 2025-01-10 21:15:31 字数 774 浏览 0 评论 0原文

TSQL 问题:

我在列中显示一个字符串值,如下所示:

Row ID, Name, Column1
1, Bob, |Gender - Male|
2, Sally, |Gender - Female| |Age - 30|
3, John, |Gender - Male|
4, Thomas, |Gender - Male|
5, Lewis, |Gender - Male| |Age - 20|

如果只有一组 ||,我只想从 Column1 中提取值,例如在另一列中,column2, 如果有一组 |,我已经

Replace(substring(column1,charindex('-',column1)+2,charindex('|',column1) ),'|','') AS column2

这样做了,它给了我值,但是我如何忽略 2 组管道,就好像有 2 组管道一样,然后它提取第一组,也不提取第二组的管道。 如果有 2 组管道,我希望能够忽略该值并将其保留在列中,并且仅更新具有 1 组管道的管道。

因此,上面的示例数据集应该如下所示:

Row ID, Name, Column1
1, Bob, Male
2, Sally, |Gender - Female| |Age - 30|
3, John, Male
4, Thomas, Male
5, Lewis, |Gender - Male| |Age - 20|

我在想也许可以以某种方式扫描第 1 列字符串值,如果有超过 1 个 -(破折号)符号,则忽略?

或者有更好的方法吗?

TSQL Question:

I have a string value in a column displayed like so:

Row ID, Name, Column1
1, Bob, |Gender - Male|
2, Sally, |Gender - Female| |Age - 30|
3, John, |Gender - Male|
4, Thomas, |Gender - Male|
5, Lewis, |Gender - Male| |Age - 20|

I only want to extract the value from the Column1 if there is only one group of ||, so for example in another column, column2,
I have done

Replace(substring(column1,charindex('-',column1)+2,charindex('|',column1) ),'|','') AS column2

this gives me the values if there is a single set of |, but how do i ignore the 2 sets of pipes as if there is 2 sets of pipes then it extracts the first one and also don't extract the 2nd set of pipes.
I want to be able to ignore and leave the value in the column if there are 2 sets of pipes and only update the ones that have 1 set of pipes.

So the above example dataset should look like this afterwards:

Row ID, Name, Column1
1, Bob, Male
2, Sally, |Gender - Female| |Age - 30|
3, John, Male
4, Thomas, Male
5, Lewis, |Gender - Male| |Age - 20|

I was thinking maybe can somehow scan the column 1 string value, if there is more than 1 -(dash) symbol then ignore?

or is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

粉红×色少女 2025-01-17 21:15:31

正如其他人提到的,您的模式设计应该重新设计为规范化的结构。至于您的 column2 示例,不确定您要在那里做什么,因为它正在寻找“=”符号。

带有 CASE WHEN 的 SQL 子字符串

这是一个返回预期输出的脚本:

DROP TABLE IF EXISTS #Temp

CREATE TABLE #Temp
(
RowID INT
,[Name] Varchar(100)
,Column1 VARCHAR(1000)
)
INSERT INTO #Temp
VALUES
(1,'Bob','|Gender - Male|')
,(2,'Sally','|Gender - Female| |Age - 30|')
,(3,'John','|Gender - Male|')
,(4,'Thomas','|Gender - Male|')
,(5,'Lewis','|Gender - Male| |Age - 20|')


SELECT *
    ,ParsedColumn = CASE 
                        /*Only parse if exactly 2 pipes in data*/
                        WHEN NumOfPipes = 2 THEN SUBSTRING(Column1,B.IdxFirstHyphen + 2,C.IdxFirstPipeAfterFirstDash-B.IdxFirstHyphen - 2)
                        /*Else return raw data from column1*/
                        ELSE Column1
                    END
FROM #Temp
CROSS APPLY (
    SELECT NumOfPipes = LEN(Column1) - LEN(REPLACE(Column1,'|',''))
        ,IdxFirstHyphen = CHARINDEX('-',Column1) /*Location of first hyphen*/
) AS B
CROSS APPLY (SELECT IdxFirstPipeAfterFirstDash = CHARINDEX('|',Column1,B.IdxFirstHyphen)) AS C /*Location of first pipe after the first hyphen*/

As others mention, your schema design should be redesigned into a normalized structure. As for your example of column2, not sure what you are trying to do there as it is looking for an "=" sign.

SQL Substring with CASE WHEN

Here's a script that returns your expected output:

DROP TABLE IF EXISTS #Temp

CREATE TABLE #Temp
(
RowID INT
,[Name] Varchar(100)
,Column1 VARCHAR(1000)
)
INSERT INTO #Temp
VALUES
(1,'Bob','|Gender - Male|')
,(2,'Sally','|Gender - Female| |Age - 30|')
,(3,'John','|Gender - Male|')
,(4,'Thomas','|Gender - Male|')
,(5,'Lewis','|Gender - Male| |Age - 20|')


SELECT *
    ,ParsedColumn = CASE 
                        /*Only parse if exactly 2 pipes in data*/
                        WHEN NumOfPipes = 2 THEN SUBSTRING(Column1,B.IdxFirstHyphen + 2,C.IdxFirstPipeAfterFirstDash-B.IdxFirstHyphen - 2)
                        /*Else return raw data from column1*/
                        ELSE Column1
                    END
FROM #Temp
CROSS APPLY (
    SELECT NumOfPipes = LEN(Column1) - LEN(REPLACE(Column1,'|',''))
        ,IdxFirstHyphen = CHARINDEX('-',Column1) /*Location of first hyphen*/
) AS B
CROSS APPLY (SELECT IdxFirstPipeAfterFirstDash = CHARINDEX('|',Column1,B.IdxFirstHyphen)) AS C /*Location of first pipe after the first hyphen*/
萌吟 2025-01-17 21:15:31

这应该非常有效,首先在 - 上分割字符串并提取带有 | 后缀的值。然后聚合并仅返回提取的值,其中column1仅分为两行:

select rowId, name, Iif(Count(*)=2,Max(Extracted),column1) Column1
from t
outer apply (
    select case when Right(value,1)='|' then Trim(Replace(value,'|','')) end Extracted
    from String_Split(column1, '-')
)x
group by rowId, name, column1;

Demo Fiddle

This should be pretty efficient, first split the string on - and extract the value with | suffixed. Then aggregate and return only extracted values where column1 was only split into two rows:

select rowId, name, Iif(Count(*)=2,Max(Extracted),column1) Column1
from t
outer apply (
    select case when Right(value,1)='|' then Trim(Replace(value,'|','')) end Extracted
    from String_Split(column1, '-')
)x
group by rowId, name, column1;

Demo Fiddle

甜点 2025-01-17 21:15:31

这是非常低效但有效的。

create function dbo.stringCounter (@Column nvarchar(255), @Character nchar(1))
returns int
AS
BEGIN
Declare @count int

select @Count=len(@Column) - len(replace(@Column,@Character,''))
Return @count
END
GO
select dbo.stringCounter(column1,'|'),column1 from TableName where dbo.stringCounter(column1,'|')=2

This is highly inefficient but works.

create function dbo.stringCounter (@Column nvarchar(255), @Character nchar(1))
returns int
AS
BEGIN
Declare @count int

select @Count=len(@Column) - len(replace(@Column,@Character,''))
Return @count
END
GO
select dbo.stringCounter(column1,'|'),column1 from TableName where dbo.stringCounter(column1,'|')=2
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文