【问题标题】:SQL Server convert select a column and convert it to a stringSQL Server convert 选择一列并将其转换为字符串
【发布时间】:2022-04-21 05:48:13
【问题描述】:

是否可以编写从表中选择列并将结果转换为字符串的语句?

理想情况下,我希望使用逗号分隔值。

例如,假设 SELECT 语句看起来像

SELECT column
FROM table
WHERE column<10

结果是包含值的列

|column|
--------
|  1   |
|  3   |
|  5   |
|  9   |

我想要字符串 "1, 3, 5, 9"

【问题讨论】:

标签: sql sql-server string select


【解决方案1】:

你可以这样做:

Fiddle demo

declare @results varchar(500)

select @results = coalesce(@results + ',', '') +  convert(varchar(12),col)
from t
order by col

select @results as results

| RESULTS |
-----------
| 1,3,5,9 |

【讨论】:

【解决方案2】:

SQL Server 2017 中有新方法:

SELECT STRING_AGG (column, ',') AS column FROM Table;

这将为您生成1,3,5,9

【讨论】:

    【解决方案3】:
    select  stuff(list,1,1,'')
    from    (
            select  ',' + cast(col1 as varchar(16)) as [text()]
            from    YourTable
            for     xml path('')
            ) as Sub(list)
    

    Example at SQL Fiddle.

    【讨论】:

      【解决方案4】:
      SELECT  CAST(<COLUMN Name> AS VARCHAR(3)) + ','
      FROM    <TABLE Name>
      FOR     XML PATH('')
      

      【讨论】:

        【解决方案5】:

        当前接受的答案不适用于多个分组。
        当您需要对列行值的类别进行操作时,请尝试此操作。

        假设我有以下数据:

        +---------+-----------+
        | column1 |  column2  |
        +---------+-----------+
        | cat     | Felon     |
        | cat     | Purz      |
        | dog     | Fido      |
        | dog     | Beethoven |
        | dog     | Buddy     |
        | bird    | Tweety    |
        +---------+-----------+
        

        我想要这个作为我的输出:

        +------+----------------------+
        | type |        names         |
        +------+----------------------+
        | cat  | Felon,Purz           |
        | dog  | Fido,Beethoven,Buddy |
        | bird | Tweety               |
        +------+----------------------+
        

        (如果你跟着:

        create table #column_to_list (column1 varchar(30), column2 varchar(30))
        insert into #column_to_list
        values 
        ('cat','Felon'),
        ('cat','Purz'),
        ('dog','Fido'),
        ('dog','Beethoven'),
        ('dog','Buddy'),
        ('bird','Tweety')
        

        )

        现在——我不想深入了解所有语法,但正如你所见,这对我们来说是初步的技巧:

        select ',' + cast(column2 as varchar(255)) as [text()]  
        from #column_to_list sub
        where column1 = 'dog'
        for xml path('')
        --Using "as [text()]" here is specific to the “for XML” line after our where clause and we can’t give a name to our selection, hence the weird column_name
        

        输出:

        +------------------------------------------+
        | XML_F52E2B61-18A1-11d1-B105-00805F49916B |
        +------------------------------------------+
        | ,Fido,Beethoven,Buddy                    |
        +------------------------------------------+
        

        您可以看到它的局限性在于它仅用于一个分组(其中 column1 = 'dog')并且它在前面留下了一个逗号,另外它被命名为怪异。

        所以,首先让我们使用 'stuff' 函数处理前导逗号,并将我们的列命名为 stuff_list:

        select stuff([list],1,1,'') as stuff_list
        from (select ',' + cast(column2 as varchar(255)) as [text()]
                 from #column_to_list sub
                 where column1 = 'dog'
                 for xml path('')
                 ) sub_query([list]) 
        --"sub_query([list])" just names our column as '[list]' so we can refer to it in the stuff function.  
        

        输出:

        +----------------------+
        |      stuff_list      |
        +----------------------+
        | Fido,Beethoven,Buddy |
        +----------------------+
        

        最后,让我们将其混入一个 select 语句,注意对 top_query 别名的引用定义了我们想要的 column1(在此处的第 5 行):

        select top_query.column1, 
                  (select stuff([list],1,1,'') as stuff_list
                 from (select ',' + cast(column2 as varchar(255)) as [text()]
                          from #column_to_list sub
                          where sub.column1 = top_query.column1
                          for xml path('')
                          ) sub_query([list])
                      ) as pet_list
        from  #column_to_list top_query
        group by column1
        order by column1
        

        输出:

        +---------+----------------------+
        | column1 |       pet_list       |
        +---------+----------------------+
        | bird    | Tweety               |
        | cat     | Felon,Purz           |
        | dog     | Fido,Beethoven,Buddy |
        +---------+----------------------+
        

        我们已经完成了。

        你可以在这里阅读更多:

        【讨论】:

          【解决方案6】:

          这是一个尝试创建一个可重复使用的以逗号分隔的字符串的列。在这种情况下,我只有一个有值的字符串,我不想要空字符串或空值。

          首先,我创建一个用户定义类型,它是一个单列表。

          -- ================================
          -- Create User-defined Table Type
          -- ================================
          USE [RSINET.MVC]
          GO
          
          -- Create the data type
          CREATE TYPE [dbo].[SingleVarcharColumn] AS TABLE 
          (
              data NVARCHAR(max)
          )
          GO
          

          该类型的真正目的是简化创建标量函数以将列放入逗号分隔值。

          -- ================================================
          -- Template generated from Template Explorer using:
          -- Create Scalar Function (New Menu).SQL
          --
          -- Use the Specify Values for Template Parameters 
          -- command (Ctrl-Shift-M) to fill in the parameter 
          -- values below.
          --
          -- This block of comments will not be included in
          -- the definition of the function.
          -- ================================================
          SET ANSI_NULLS ON
          GO
          SET QUOTED_IDENTIFIER ON
          GO
          -- =============================================
          -- Author:  Rob Peterson        
          -- Create date: 8-26-2015
          -- Description: This will take a single varchar column and convert it to
          -- comma separated values.
          -- =============================================
          CREATE FUNCTION fnGetCommaSeparatedString 
          (
              -- Add the parameters for the function here
              @column AS [dbo].[SingleVarcharColumn] READONLY
          )
          RETURNS VARCHAR(max)
          AS
          BEGIN
          -- Declare the return variable here
          DECLARE @result VARCHAR(MAX)
          DECLARE @current VARCHAR(MAX)
          DECLARE @counter INT
          DECLARE @c CURSOR
          
          SET @result = ''
          SET @counter = 0
          -- Add the T-SQL statements to compute the return value here
          SET @c = CURSOR FAST_FORWARD
              FOR SELECT COALESCE(data,'') FROM @column
              OPEN @c
              FETCH NEXT FROM @c
              INTO @current
              WHILE @@FETCH_STATUS = 0
              BEGIN
                  IF @result <> '' AND @current <> '' SET @result = @result + ',' + @current
                  IF @result = '' AND @current <> '' SET @result = @current
              FETCH NEXT FROM @c
              INTO @current
              END
              CLOSE @c
              DEALLOCATE @c
          -- Return the result of the function
          RETURN @result
          
          END
          GO
          

          现在,使用它。我将要转换为逗号分隔字符串的列选择为 SingleVarcharColumn 类型。

          DECLARE @s as SingleVarcharColumn
          
          INSERT INTO @s VALUES ('rob')
          INSERT INTO @s VALUES ('paul')
          INSERT INTO @s VALUES ('james')
          INSERT INTO @s VALUES (null)
          
          
          INSERT INTO @s
          SELECT iClientID FROM [dbo].tClient
          
          SELECT [dbo].fnGetCommaSeparatedString(@s)
          

          为了得到这样的结果。

          rob,paul,james,1,9,10,11,12,13,14,15,16,18,19,23,26,27,28,29,30,31,32,34,35 ,36,37,38,39,40,41,42,44,45,46,47,48,49,50,52,53,54,56,57,59,60,61,62,63,64 ,65,66,67,68,69,70,71,72,74,75,76,77,78,81,82,83,84,87,88,90,91,92,93,94,98,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,​​141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159

          我将 SingleVarcharColumn 类型中的数据列设置为 NVARCHAR(MAX),这可能会损害性能,但我一直在寻找灵活性,它的运行速度足以满足我的目的。如果它是一个 varchar 并且如果它有一个固定的和更小的宽度,它可能会更快,但我没有测试过。

          【讨论】:

            【解决方案7】:
            ALTER PROCEDURE [dbo].[spConvertir_CampoACadena]( @nomb_tabla   varchar(30),
                                      @campo_tabla  varchar(30),
                                      @delimitador  varchar(5),
                                      @respuesta    varchar(max) OUTPUT
            )
            AS
            DECLARE @query      varchar(1000),
                @cadena     varchar(500)
            BEGIN
              SET @query = 'SELECT @cadena  = COALESCE(@cadena + '''+ @delimitador +''', '+ '''''' +') + '+ @campo_tabla + ' FROM '+@nomb_tabla
              --select @query
              EXEC(@query)
              SET @respuesta = @cadena  
            END
            

            【讨论】:

            • 这似乎与问题没有太大关系,但即使是,请对您发布的代码进行一些解释。纯代码转储不是很有用。
            【解决方案8】:

            您可以使用以下方法:

            select
            STUFF(
                    (
                    select ', ' + CONVERT(varchar(10), ID) FROM @temp
                    where ID<50
            group by ID for xml path('')
                    ), 1, 2, '') as IDs
            

            实施:

            Declare @temp Table(
            ID int
            )
            insert into @temp
            (ID)
            values
            (1)
            insert into @temp
            (ID)
            values
            (3)
            insert into @temp
            (ID)
            values
            (5)
            insert into @temp
            (ID)
            values
            (9)
            
             select
            STUFF(
                    (
                    select ', ' + CONVERT(varchar(10), ID) FROM @temp
                    where ID<50
            group by ID for xml path('')
                    ), 1, 2, '') as IDs
            

            结果将是:

            【讨论】:

              【解决方案9】:

              --------------- 很容易找到喜欢它 --------------- -

              SELECT STUFF((
                      select ','+ name 
                      from tblUsers
                      FOR XML PATH('')
                      )
                      ,1,1,'') AS names
              
              name
              ---------
              mari, joan, carls
              ---------
              

              【讨论】:

                【解决方案10】:

                使用LISTAGG功能, 前任。 SELECT LISTAGG(colmn) FROM table_name;

                【讨论】:

                • LISTAGG 不是 SQL Server 支持的函数。
                • 适用于 redshift sql
                【解决方案11】:

                使用最简单的方法-

                SELECT GROUP_CONCAT(Column) from table
                

                【讨论】:

                • GROUP_CONCAT 不是公认的内置函数 | Microsoft SQL Server 企业版 14.0.3370.1
                【解决方案12】:
                +------+----------------------+
                | type |        names         |
                +------+----------------------+
                | cat  | Felon                |
                | cat  | Purz                 |
                | dog  | Fido                 |
                | dog  | Beethoven            |
                | dog  | Buddy                |
                | bird | Tweety               |
                +------+----------------------+
                

                select group_concat(name) from Pets
                group by type
                

                在这里,您可以在单个 SQL 中轻松获得答案,并且通过在 SQL 中使用 group by,您可以根据该列值分隔结果。您也可以使用自己的自定义分隔符来拆分值

                结果:

                +------+----------------------+
                | type |        names         |
                +------+----------------------+
                | cat  | Felon,Purz           |
                | dog  | Fido,Beethoven,Buddy |
                | bird | Tweety               |
                +------+----------------------+
                

                【讨论】:

                  猜你喜欢
                  • 2021-07-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-12-15
                  相关资源
                  最近更新 更多