2011-03-04 36 views
26

Tôi có một chức năng sql đó bao gồm mã này:SQL Query - Kết nối Kết quả thành một chuỗi

DECLARE @CodeNameString varchar(100) 

SELECT CodeName FROM AccountCodes ORDER BY Sort 

tôi cần phải nối tất cả các kết quả từ các truy vấn chọn vào CodeNameString.

Rõ ràng là vòng lặp FOREACH trong mã C# sẽ làm điều này, nhưng làm cách nào để thực hiện điều đó trong SQL?

+1

Phiên bản ** nào của SQL Server ?? –

+1

có thể trùng lặp của [SQL Server: Tôi có thể Comma Delimit nhiều hàng vào một cột?] (Http://stackoverflow.com/questions/2046037/sql-server-can-i-comma-delimit-multiple-rows-into- một cột) và: http://stackoverflow.com/questions/1817985/how-do-i-create-a-comma-separated-list-using-a-sql-query –

+0

đã trả lời nhiều lần ... nhưng xem ra, không phải tất cả các triển khai ghép nối FOR XML PATH sẽ xử lý đúng các ký tự đặc biệt XML (<, &, >, v.v.) giống như câu trả lời của tôi cho câu trả lời trước sẽ: http://stackoverflow.com/questions/5031204/does-t-sql-have- a-aggregate-function-to-concatenate-strings/5031297 # 5031297 –

Trả lời

68

Nếu bạn đang sử dụng SQL Server 2005 trở lên, bạn có thể sử dụngnàylừa:

DECLARE @CodeNameString varchar(100) 

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

Các FOR XML PATH('') cơ bản concatenates chuỗi lại với nhau thành một, kết quả XML dài (cái gì đó như ,code1,code2,code3 vv) và các STUFF đặt một "không có gì" ký tự ở ký tự đầu tiên, ví dụ xóa sạch dấu phẩy đầu tiên "thừa", để cung cấp cho bạn kết quả mà bạn có thể đang tìm kiếm.

UPDATE: OK - Tôi hiểu những ý kiến ​​- nếu văn bản của bạn trong bảng cơ sở dữ liệu đã được chứa các ký tự như <, > hoặc &, sau đó giải pháp hiện tại của tôi sẽ trên thực tế mã hóa những thành &lt;, &gt;, và &amp; .

Nếu bạn gặp sự cố với mã hóa XML đó - thì có, bạn phải xem giải pháp được đề xuất bởi @KM cũng hoạt động cho các ký tự đó. Một từ của cảnh báo từ tôi: cách tiếp cận này là nhiều hơn tài nguyên và chế biến chuyên sâu - chỉ để bạn biết.

+14

** điều này sẽ KHÔNG xử lý đúng các ký tự đặc biệt XML ('<', '&' , '>', v.v.) ** giống như câu trả lời trước của tôi, xem tại đây: http://stackoverflow.com/questions/5031204/does-t-sql-have-an -gregregate-function-to-concatenate-strings/5031297 # 5031297 –

+0

@marc_s Điều này rất nguy hiểm. Tôi phải lặp lại bình luận của KM ở trên. – jnm2

+0

@ jnm2: đã đồng ý - ** nếu ** ai đó cần những ký tự đặc biệt đó thì giải pháp của "KM" là cách để đi. ** HOWEVER: ** nó ** A LOT ** chế biến nhiều hơn và do đó tôi khuyên bạn nên sử dụng nó ** chỉ ** nếu bạn thực sự phải có vài ký tự đặc biệt XML trong đầu ra của bạn –

23
DECLARE @CodeNameString varchar(max) 
SET @CodeNameString='' 

SELECT @[email protected]+CodeName FROM AccountCodes ORDER BY Sort 
SELECT @CodeNameString 
+0

đơn giản và hoạt động hoàn hảo. Cảm ơn. – Ben

+0

Câu trả lời đơn giản và thanh lịch. Có bất kỳ hạn chế nào đối với việc sử dụng phương pháp này không? (Các giá trị NULL được xử lý bởi biến thể của James Wisemann trên câu trả lời này) – Pac0

10

@ câu trả lời AlexanderMP là đúng, nhưng bạn cũng có thể xem xét xử lý null với coalesce:

declare @CodeNameString nvarchar(max) 
set @CodeNameString = null 
SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes 
select @CodeNameString 
+1

Vâng, tôi quên mất coalesce/isnull. Nhưng nó sẽ không có ý nghĩa hơn để kiểm tra 'CodeName' thay vì' @ CodeNameString'? Người ta có thể mất dữ liệu theo cách này. Tốt hơn, thay vì thaneste, nó sẽ có ý nghĩa để sử dụng đồng bằng cũ 'Where CodeName không phải là null'. – AlexanderMP

4

Đối với SQL Server 2005 trở lên sử dụng Coalesce cho nulls và tôi đang sử dụng Cast or Convert nếu có numeric values -

declare @CodeNameString nvarchar(max) 
select @CodeNameString = COALESCE(@CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort 
select @CodeNameString 
+0

100 là một chút nhỏ, bạn không nghĩ ;-) –

+0

@ James- Hmm..just sao chép rằng từ Câu hỏi của OP đã cập nhật nó ngay bây giờ..thanks ... btw dang nó bạn đã đánh bại tôi với nó .. – Vishal

0

Dưới đây là một ví dụ thực tế khác hoạt động tốt ít nhất với bản phát hành năm 2008 (và sau này).

Đây là truy vấn ban đầu trong đó sử dụng đơn giản max() để có được ít nhất một trong các giá trị:

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 

Phiên bản cải tiến, trong đó cải thiện chính là chúng ta hiển thị tất cả các giá trị dấu phẩy tách ra:

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 

Lưu ý rằng chúng tôi đã giải quyết tất cả các sự cố có thể xảy ra NULL trường hợp mà tôi có thể nghĩ đến và chúng tôi cũng đã khắc phục lỗi mà chúng tôi nhận được cho các giá trị số (phân loại trường).

2

từ msdn Không sử dụng biến trong câu lệnh SELECT để nối các giá trị (nghĩa là, để tính các giá trị tổng hợp). Kết quả truy vấn bất ngờ có thể xảy ra.Điều này là do tất cả các biểu thức trong danh sách SELECT (bao gồm các bài tập) không được đảm bảo thực thi chính xác một lần cho mỗi hàng đầu ra

Ở trên có vẻ như việc ghép nối như đã thực hiện ở trên không hợp lệ. so với các hàng được trả về bởi số

Các vấn đề liên quan