根據某一字段值相同合並字符串 - - SQL


 

   做項目的過程中,遇到一個問題,相同 id,不同value的記錄希望合並成一條記錄,value以逗號分隔,從網上搜了搜解決方案,整理如下,備忘。

 

一、           字符串合並

表名:test

字段:

         id               int

         name        nvarchar(50)

字段值:

         

期望結果:

         id               nameStr

         -----------------------------

         1                a,b,c

         2                d,e

         3                f

SQL實現:

1、 利用函數解決

 

-- 創建處理函數

CREATE FUNCTION dbo.f_str(@id int)

RETURNS varchar(8000)

AS

BEGIN

    DECLARE @r varchar(8000)

    SET @r = ''

    SELECT @r = @r + ',' + [name]

    FROM [test]

    WHERE [id]=@id

    RETURN STUFF(@r, 1, 1, '')

END

GO

 

-- 調用函數

SELECT [id], [nameStr]=dbo.f_str(id)

FROM [test]

GROUP BY [id]

 

運行結果:

  

 

 

2、 直接用SQL解決

 

SELECT *

FROM(

    SELECT DISTINCT [id]

    FROM [test]

)A

OUTER APPLY(

    SELECT

       [nameStr]= STUFF(REPLACE(REPLACE(

       (

           SELECT [name] FROM [test] N

           WHERE [id] = A.id

           FOR XML AUTO

       ), '<N name="', ','), '"/>', ''), 1, 1, '')

)M

 

運行結果:

  

 

看不懂這個SQL不要緊,下面有詳細分析

 

二、           詳細分析

1、  STUFF

作用:

         STUFF函數將字符串插入另一字符串。它在第一個字符串中從開始位置刪

除指定長度的字符;然后將第二個字符串插入第一個字符串的開始位置。

語法:

        STUFF ( character_expression , start , length ,character_expression )

參數:

character_expression

                     一個字符數據表達式。character_expression可以是常量、變量,也可

                     以是字符列或二進制數據列。

start

                     一個整數值,指定刪除和插入的開始位置。如果startlength為負,

      則返回空字符串。如果start比第一個character_expression長,則返

      回空字符串。start可以是bigint類型。

                             length

                                        一個整數,指定要刪除的字符數。如果length比第一個

character_expression長,則最多刪除到第一個character_expression

中的最后一個字符。Length可以是bigint類型。

返回類型:

         如果character_expression是受支持的字符數據類型,則返回字符數據。

 如果character_expression是一個受支持的 binary 數據類型,則返回二

 進制數據。

注釋:

   如果開始位置或長度值是負數,或者如果開始位置大於第一個字符串的長

 度,將返回空字符串。如果要刪除的長度大於第一個字符串的長度,將刪

 除到第一個字符串中的最后一個字符。如果結果值大於返回類型支持的最

 大值,則產生錯誤。

示例:

              SELECT STUFF('abcdef', 2, 3, 'ijklmn');

GO

結果:

         

 

SELECT STUFF('abcdef', -2, 3, 'ijklmn');

GO

結果:

         

 

SELECT STUFF('abcdef', 2, 10, 'ijklmn');

GO

結果:

         

 

2、  CROSS APPLY 與 OUTER APPLY

 使用 APPLY 運算符可以為實現查詢操作的外部表表達式返回的每個行調用表值函數。表值函數作為右輸入,外部表表達式作為左輸入。通過對右輸入求值來獲得左輸入每一行的計算結果,生成的行被組合起來作為最終輸出。APPLY 運算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。

 APPLY 有兩種形式:CROSS APPLY 和 OUTER APPLY。CROSS APPLY 僅返回外部表中通過表值函數生成結果集的行。OUTER APPLY 既返回生成結果集的行,也返回不生成結果集的行,其中表值函數生成的列中的值為NULL。

 

用示例來區分兩者:

第一張表:

            表名:student

            字段名:

                     

            字段值:

                     

第二張表:

            表名:student_class

            字段名:

                     

            字段值:

                     

 

CROSS APPLY

SELECT *

FROM [student] a

CROSS APPLY(

  SELECT [class], [score]

  FROM [student_class]

  WHERE student_id = a.id

) b

 

運行結果:

  

 

 

OUTER APPLY

SELECT *

FROM [student] a

OUTER APPLY(

  SELECT [class], [score]

  FROM [student_class]

  WHERE student_id = a.id

) b

 

運行結果:

     

 

3、  FOR XML AUTO

將結果轉換為XML結構,例如對於上面2中的student表,執行以下語句

SELECT *

FROM [student]

FOR XML AUTO

 

運行結果:

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM