SQL Server 中的字符串分割

发布于 2025-01-15 09:46:46 字数 1098 浏览 2 评论 0原文

我有一个关于 SQL Server 的问题:如何使用 _ 分割字符串并获取所需的格式。

如果我们没有 - 符号,则保留空值。

表:

CREATE TABLE [dbo].[student]
(
    [sid] [int] NULL,
    [course] [varchar](500) NULL,
    [name] [varchar](50) NULL
) 

INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (1, N'database-sql;FE-Java', N'abc')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (2, N'FE-net;database-oracle;FE-python', N'xyz')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (3, N'test', N'axy')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (4, N'FE-python-java;base-mysql', N'anr')

基于这些数据,我想要这样的输出:

Sid | course            |name 
----+-------------------+-----
1   |sql,java           |abc
2   |net,oracle,python  |xyz
3   |                   |axy
4   |python,java,mysql  |anr

我已经尝试使用这样的 SQL:

select 
    sid,
    substring([course], charindex([course], '-') + 1, len([course])) course,
    name 
from 
    student

但是,此查询没有返回预期的结果。

如何在 SQL Server 中编写查询来完成此任务?

I have a question about SQL Server: how to split a string using _ and get required format.

If we do not have - symbol then keep empty value.

Table :

CREATE TABLE [dbo].[student]
(
    [sid] [int] NULL,
    [course] [varchar](500) NULL,
    [name] [varchar](50) NULL
) 

INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (1, N'database-sql;FE-Java', N'abc')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (2, N'FE-net;database-oracle;FE-python', N'xyz')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (3, N'test', N'axy')
INSERT INTO [dbo].[student] ([sid], [course], [name]) 
VALUES (4, N'FE-python-java;base-mysql', N'anr')

Based on this data, I want output like this:

Sid | course            |name 
----+-------------------+-----
1   |sql,java           |abc
2   |net,oracle,python  |xyz
3   |                   |axy
4   |python,java,mysql  |anr

I have tried with SQL like this:

select 
    sid,
    substring([course], charindex([course], '-') + 1, len([course])) course,
    name 
from 
    student

This query however is not returning the expected results.

How can I write a query to achieve this task in SQL Server?

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

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

发布评论

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

评论(3

柏林苍穹下 2025-01-22 09:46:46

请尝试以下解决方案。

它将从 SQL Server 2016 开始运行。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (sid int NULL, course varchar(500) NULL, name varchar(50) NULL); 
INSERT INTO @tbl (sid, course, name) VALUES 
(1, N'database-sql;FE-Java', N'abc'),
(2, N'FE-net;database-oracle;FE-python', N'xyz'),
(3, N'test', N'axy'),
(4, N'FE-python-java;base-mysql', N'anr');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = ';'
    , @comma CHAR(1) = ','
    , @dash CHAR(1) = '-';

SELECT tbl.*
    , REPLACE(STUFF((SELECT @comma + IIF(pos=0,'',SUBSTRING(value, pos + 1, LEN(value)))
            FROM @tbl AS tbl_inner
                CROSS APPLY STRING_SPLIT(tbl_inner.course, @separator) AS ss
                CROSS APPLY (SELECT CHARINDEX(@dash, value)) AS t(pos)
            WHERE tbl_inner.sid = tbl.sid
            FOR XML PATH('')), 1, 1, ''),@dash,@comma) AS Result
FROM @tbl AS tbl; 

输出

+-----+----------------------------------+------+-------------------+
| sid |              course              | name |      Result       |
+-----+----------------------------------+------+-------------------+
|   1 | database-sql;FE-Java             | abc  | sql,Java          |
|   2 | FE-net;database-oracle;FE-python | xyz  | net,oracle,python |
|   3 | test                             | axy  |                   |
|   4 | FE-python-java;base-mysql        | anr  | python,java,mysql |
+-----+----------------------------------+------+-------------------+

Please try the following solution.

It will work starting from SQL Server 2016 onwards.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (sid int NULL, course varchar(500) NULL, name varchar(50) NULL); 
INSERT INTO @tbl (sid, course, name) VALUES 
(1, N'database-sql;FE-Java', N'abc'),
(2, N'FE-net;database-oracle;FE-python', N'xyz'),
(3, N'test', N'axy'),
(4, N'FE-python-java;base-mysql', N'anr');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = ';'
    , @comma CHAR(1) = ','
    , @dash CHAR(1) = '-';

SELECT tbl.*
    , REPLACE(STUFF((SELECT @comma + IIF(pos=0,'',SUBSTRING(value, pos + 1, LEN(value)))
            FROM @tbl AS tbl_inner
                CROSS APPLY STRING_SPLIT(tbl_inner.course, @separator) AS ss
                CROSS APPLY (SELECT CHARINDEX(@dash, value)) AS t(pos)
            WHERE tbl_inner.sid = tbl.sid
            FOR XML PATH('')), 1, 1, ''),@dash,@comma) AS Result
FROM @tbl AS tbl; 

Output

+-----+----------------------------------+------+-------------------+
| sid |              course              | name |      Result       |
+-----+----------------------------------+------+-------------------+
|   1 | database-sql;FE-Java             | abc  | sql,Java          |
|   2 | FE-net;database-oracle;FE-python | xyz  | net,oracle,python |
|   3 | test                             | axy  |                   |
|   4 | FE-python-java;base-mysql        | anr  | python,java,mysql |
+-----+----------------------------------+------+-------------------+
寂寞陪衬 2025-01-22 09:46:46

使用这个查询:

SELECT 
   sid,
   course,
   name,
   STRING_AGG(CA2.C,',') as result 
FROM student AS s
CROSS APPLY(
   SELECT * FROM
   string_split(s.course,';')
)AS CA1
CROSS APPLY(
   SELECT SUBSTRING(CA1.value, charindex('-',CA1.value) + 1, len(CA1.value)) c 
) AS CA2 
GROUP BY     
   sid,
   course,
   name

use this query:

SELECT 
   sid,
   course,
   name,
   STRING_AGG(CA2.C,',') as result 
FROM student AS s
CROSS APPLY(
   SELECT * FROM
   string_split(s.course,';')
)AS CA1
CROSS APPLY(
   SELECT SUBSTRING(CA1.value, charindex('-',CA1.value) + 1, len(CA1.value)) c 
) AS CA2 
GROUP BY     
   sid,
   course,
   name
瞳孔里扚悲伤 2025-01-22 09:46:46
ALTER FUNCTION [dbo].[Split]    
(     
    @String VARCHAR(max),     
    @Delimiter VARCHAR(5)     
)     
RETURNS @SplittedValues TABLE     
(     
   OccurenceId SMALLINT IDENTITY(1,1),     
   SplitValue VARCHAR(max)     
)     
AS     
BEGIN     
    DECLARE @SplitLength INT     
        
    WHILE LEN(@String) > 0     
    BEGIN     
        SELECT @SplitLength = (CASE CHARINDEX(@Delimiter,@String) WHEN 0 THEN     
            LEN(@String) 
        ELSE 
            CHARINDEX(@Delimiter,@String) -1  END)     
        INSERT INTO @SplittedValues     
        SELECT SUBSTRING(@String,1,@SplitLength)     
        SELECT @String = (CASE LTRIM(RTRIM(LEN(@String) - @SplitLength)) WHEN 0 THEN 
            ''     
        ELSE 
            RIGHT(@String, LTRIM(RTRIM(LEN(@String) - @SplitLength - 1))) END)     
        END     
    RETURN     
END
ALTER FUNCTION [dbo].[Split]    
(     
    @String VARCHAR(max),     
    @Delimiter VARCHAR(5)     
)     
RETURNS @SplittedValues TABLE     
(     
   OccurenceId SMALLINT IDENTITY(1,1),     
   SplitValue VARCHAR(max)     
)     
AS     
BEGIN     
    DECLARE @SplitLength INT     
        
    WHILE LEN(@String) > 0     
    BEGIN     
        SELECT @SplitLength = (CASE CHARINDEX(@Delimiter,@String) WHEN 0 THEN     
            LEN(@String) 
        ELSE 
            CHARINDEX(@Delimiter,@String) -1  END)     
        INSERT INTO @SplittedValues     
        SELECT SUBSTRING(@String,1,@SplitLength)     
        SELECT @String = (CASE LTRIM(RTRIM(LEN(@String) - @SplitLength)) WHEN 0 THEN 
            ''     
        ELSE 
            RIGHT(@String, LTRIM(RTRIM(LEN(@String) - @SplitLength - 1))) END)     
        END     
    RETURN     
END
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文