テーブルから列を選択し、結果を文字列に変換するステートメントを書くことは可能ですか?
理想的には、コンマ区切りの値が必要です。
たとえば、SELECTステートメントが次のように見えるとしましょう
SELECT column
FROM table
WHERE column<10
結果は値を持つ列です
|column|
--------
| 1 |
| 3 |
| 5 |
| 9 |
結果として文字列「1、3、5、9」が必要です
次のようにできます:
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 |
select stuff(list,1,1,'')
from (
select ',' + cast(col1 as varchar(16)) as [text()]
from YourTable
for xml path('')
) as Sub(list)
SQL Server 2017には新しい方法があります。
SELECT STRING_AGG (column, ',') AS column FROM Table;
1,3,5,9
が生成されます
SELECT CAST(<COLUMN Name> AS VARCHAR(3)) + ','
FROM <TABLE Name>
FOR XML PATH('')
現在受け入れられている答えは、複数のグループ化では機能しません。
列の行値のカテゴリを操作する必要がある場合にこれを試してください。
次のデータがあると仮定します。
+---------+-----------+
| 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 |
+------------------------------------------+
1つのグループ(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ステートメントに変換し、必要なcolumn1を定義するtop_queryエイリアスへの参照に注目します(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 |
+---------+----------------------+
これで完了です。
詳細はこちらをご覧ください:
これは、コンマ区切りの文字列に再利用可能な列を作成する際の突き刺しです。この場合、値を持つ文字列は1つだけで、空の文字列やnullは必要ありません。
最初に、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)
このような結果を得るには。
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で、固定幅が小さい場合はおそらく高速ですが、テストしていません。
次の方法を使用できます。
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
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