Sql-Server

子字元串中的 Mssql 子查詢

  • December 7, 2020

我需要刪除我的子查詢的最後一個字元,但我無法弄清楚如何在子選擇中引用我的子查詢,因為我需要它的長度。

子選擇收集所有行並通過附加分隔符“;”將它們轉換為單個字元串。

這就是我需要的:

(SUBSTRING(
   (SELECT 
                   d1.name +'; '
   FROM   
                   data1 d1 
                   inner join data2 d2
                   on d1.id = d2.id
   WHERE   
                   d1.id = dOfOutterSelect.id 
   ORDER BY
                   d1.CreatedOn FOR XML PATH('') 

   ),
LENGTH(),1)) 

As "Row name",

使用STUFF(...)T-SQL 函式去除最後一個字元。首先REVERSE是查詢結果中的字元串,然後使用STUFF,然後REVERSE再次使用結果。

像這樣:

SELECT REVERSE(STUFF(REVERSE('this is my string'), 1, 1, ''))

結果如下所示:

這是STUFFREVERSE的 Microsoft Docs 頁面。

實際上,更仔細地查看您的查詢,您可以稍微改進它以消除該REVERSE函式的使用。以下面的範例為例,我將數據庫中所有列的名稱與分號分隔符連接起來。

SELECT STUFF((
   SELECT N'; ' + c.name
   FROM sys.columns c
   FOR XML PATH (N'')
   ), 1, 2, N'');

我在字元串的開頭添加分號,然後簡單地STUFF將前 2 個字元替換為“nothing”。

所以結果看起來像:

較新版本的 SQL Server (2017+) 支持使用STRING_AGG可以顯著簡化此類查詢的聚合。要獲得與我上面的查詢相同的輸出,請使用STRING_AGG,您可以這樣編寫:

SELECT STRING_AGG(CONVERT(nvarchar(max), c.name), N'; ')
FROM sys.columns c;

在列周圍有CONVERT(nvarchar(max), ...)環繞c.name以強制STRING_AGG函式使用足夠長的字元串來包含我的數據庫中的所有列名。如果你忽略它,SQL Server 會報告一個錯誤:

消息 9829,級別 16,狀態 1,第 10 行

STRING_AGG 聚合結果超出了 8000 字節的限制。使用 LOB 類型來避免結果截斷。

引用自:https://dba.stackexchange.com/questions/280907