47

このコードを含む SQL 関数があります。

DECLARE @CodeNameString varchar(100)

SELECT CodeName FROM AccountCodes ORDER BY Sort

選択クエリからのすべての結果を CodeNameString に連結する必要があります。

明らかに、C# コードの FOREACH ループでこれが行われますが、SQL ではどのように行うのでしょうか?

4

6 に答える 6

93

SQL Server 2005 以降を使用している場合は、次のFOR XML PATH & STUFFトリックを使用できます。

DECLARE @CodeNameString varchar(100)

SELECT 
   @CodeNameString = STUFF( (SELECT ',' + CodeName 
                             FROM dbo.AccountCodes 
                             ORDER BY Sort
                             FOR XML PATH('')), 
                            1, 1, '')

基本的に、FOR XML PATH('')文字列を 1 つの長い XML 結果 (,code1,code2,code3など)に連結STUFFし、最初の文字に「何もない」文字を配置します。たとえば、「余分な」最初のコンマを消去して、おそらく探している。

更新: OK - コメントを理解しました - データベース テーブル内のテキストに<>または などの文字が既に含まれている&場合、現在のソリューション&lt;は実際にそれらを、&gt;、 にエンコードし&amp;ます。

その XML エンコーディングに問題がある場合は、@KM によって提案された解決策を調べる必要があります。これは、これらの文字でも機能します。私からの警告の 1 つ: このアプローチは、より多くのリソースと処理を集中的に使用します。

于 2011-03-04T16:24:06.493 に答える
28
DECLARE @CodeNameString varchar(max)
SET @CodeNameString=''

SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT @CodeNameString
于 2011-03-04T16:18:31.280 に答える
12

@AlexanderMPの答えは正しいですが、nullの処理を次のように検討することもできますcoalesce

declare @CodeNameString  nvarchar(max)
set @CodeNameString = null
SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes  
select @CodeNameString
于 2011-03-04T16:22:26.100 に答える
5

SQL Server 2005以降の場合は、 Coalesce forを使用し、次の場合はCastまたはConvertnullsを使用しています-numeric values

declare @CodeNameString  nvarchar(max)
select  @CodeNameString = COALESCE(@CodeNameString + ',', '')  + Cast(CodeName as varchar) from AccountCodes  ORDER BY Sort
select  @CodeNameString
于 2011-03-04T16:23:00.173 に答える
2

msdn から SELECT ステートメントで変数を使用して値を連結しないでください (つまり、集計値を計算します)。予期しないクエリ結果が発生する可能性があります。これは、SELECT リスト内のすべての式 (割り当てを含む) が、出力行ごとに 1 回だけ実行されることが保証されていないためです。

上記は、選択によって返される行よりも多くの回数割り当てが行われる可能性があるため、上記の連結は無効であると言っているようです

于 2014-11-25T16:46:54.947 に答える
0

これは、少なくとも 2008 リリース (およびそれ以降) で正常に動作する別の実際の例です。

これは、simplemax()を使用して少なくとも 1 つの値を取得する元のクエリです。

SELECT option_name, Field_M3_name, max(Option_value) AS "Option value", max(Sorting) AS "Sorted"
FROM Value_list group by Option_name, Field_M3_name
ORDER BY option_name, Field_M3_name

改善されたバージョン。主な改善点は、すべての値をコンマで区切って表示することです。

SELECT from1.keys, from1.option_name, from1.Field_M3_name,

 Stuff((SELECT DISTINCT ', ' + [Option_value] FROM Value_list from2
  WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Option values",

 Stuff((SELECT DISTINCT ', ' + CAST([Sorting] AS VARCHAR) FROM Value_list from2
  WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Sorting"

FROM ((SELECT DISTINCT COALESCE(Option_name,'') + '|' + COALESCE(Field_M3_name,'') AS keys, Option_name, Field_M3_name FROM Value_list)
-- WHERE
) from1
ORDER BY keys

考えられるすべての大文字と小文字の問題を解決したことに注意してくださいNULL。また、数値で発生したエラー (フィールドの並べ替え) も修正しました。

于 2014-07-11T10:19:59.170 に答える