31

Is it possible to write a statement that selects a column from a table and converts the results to a string?

Ideally I would want to have comma separated values.

For example, say that the SELECT statement looks something like

SELECT column
FROM table
WHERE column<10

and the result is a column with values

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

I want as a result the string "1, 3, 5, 9"

4

11 回答 11

71

你可以这样做:

小提琴演示

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 |
于 2013-04-24T13:27:32.413 回答
18

SQL Server 2017 中有一个新方法:

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

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

于 2018-12-19T20:04:04.837 回答
12
select  stuff(list,1,1,'')
from    (
        select  ',' + cast(col1 as varchar(16)) as [text()]
        from    YourTable
        for     xml path('')
        ) as Sub(list)

SQL Fiddle 的示例。

于 2013-04-24T13:26:04.533 回答
4
SELECT  CAST(<COLUMN Name> AS VARCHAR(3)) + ','
FROM    <TABLE Name>
FOR     XML PATH('')
于 2016-08-15T11:01:35.670 回答
3

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

假设我有以下数据:

+---------+-----------+
| 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 |
+---------+----------------------+

我们完成了。

你可以在这里阅读更多:

于 2018-09-06T22:02:17.130 回答
1

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

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

-- ================================
-- 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)

得到这样的结果。

抢,保罗,詹姆斯,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 并且宽度固定且较小,它可能会更快,但我还没有测试过。

于 2015-08-26T14:59:25.153 回答
0
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
于 2014-09-25T19:44:26.647 回答
0

您可以使用以下方法:

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

结果将是:

在此处输入图像描述

于 2017-08-29T09:41:22.003 回答
-1

使用LISTAGG函数,例如。SELECT LISTAGG(colmn) FROM table_name;

于 2020-02-22T09:44:27.870 回答
-1
+------+----------------------+
| 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               |
+------+----------------------+
于 2020-12-28T16:44:04.187 回答
-1

使用最简单的方法 -

SELECT GROUP_CONCAT(Column) from table
于 2020-04-04T05:12:06.270 回答