SQL Server中的自定义聚合函数(concat)

Ste*_*ger 23 sql sql-server-2005 aggregate-functions aggregation sql-server-2008

问题:我想编写一个自定义聚合函数,用于连接group by上的字符串.

这样我就能做到

SELECT SUM(FIELD1) as f1, MYCONCAT(FIELD2)  as f2
FROM TABLE_XY
GROUP BY FIELD1, FIELD2
Run Code Online (Sandbox Code Playgroud)

我找到的只是SQL CRL聚合函数,但我需要SQL,没有CLR.



编辑:1
查询应如下所示:

   SELECT SUM(FIELD1) as f1, MYCONCAT(FIELD2)  as f2
    FROM TABLE_XY
    GROUP BY FIELD0
Run Code Online (Sandbox Code Playgroud)



编辑2:
没有CLR,这是不可能的.
但是,可以修改旁观者的子选择答案,因此不会对特殊字符进行XML编码.

对此的微妙更改是在"FOR XML PATH"之后添加:

 TYPE 
                  ).value('.[1]', 'nvarchar(MAX)') 
Run Code Online (Sandbox Code Playgroud)

这里举几个例子

DECLARE @tT table([A] varchar(200), [B] varchar(200));

INSERT INTO @tT VALUES ('T_A', 'C_A');
INSERT INTO @tT VALUES ('T_A', 'C_B');
INSERT INTO @tT VALUES ('T_B', 'C_A');
INSERT INTO @tT VALUES ('T_C', 'C_A');
INSERT INTO @tT VALUES ('T_C', 'C_B');
INSERT INTO @tT VALUES ('T_C', 'C_C');

SELECT 
      A AS [A]
      ,
      ( 
            STUFF 
            ( 
                    ( 
                             SELECT DISTINCT 
                                   ', ' + tempT.B AS wtf 
                             FROM @tT AS tempT 
                             WHERE (1=1) 
                             --AND tempT.TT_Status = 1 
                             AND tempT.A = myT.A 
                             ORDER BY wtf 
                             FOR XML PATH, TYPE 
                    ).value('.[1]', 'nvarchar(MAX)') 
                    , 1, 2, '' 
            ) 
      ) AS [B] 
FROM @tT AS myT
GROUP BY A 





SELECT 
      ( 
            SELECT 
                  ',äöü<>' + RM_NR AS [text()] 
            FROM T_Room 
            WHERE RM_Status = 1 
            ORDER BY RM_NR 
            FOR XML PATH('') 

      ) AS XmlEncodedNoNothing  


      ,
      SUBSTRING
      (
            (
                  SELECT 
                        ',äöü<>' + RM_NR  AS [data()] 
                  FROM T_Room 
                  WHERE RM_Status = 1 
                  ORDER BY RM_NR 
                  FOR XML PATH('')
            )
            ,2
            ,10000
      ) AS XmlEncodedSubstring  


      ,
      ( 
            STUFF 
            ( 
                  ( 
                        SELECT ',äöü<>' + RM_NR + CHAR(10) 
                        FROM T_Room 
                        WHERE RM_Status = 1 
                        ORDER BY RM_NR 
                        FOR XML PATH, TYPE 
                  ).value('.[1]', 'nvarchar(MAX)') 
                  , 1, 1, '' 
            ) 
      ) AS XmlDecodedStuffInsteadSubstring   
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 13

您无法在CLR之外编写自定义聚合.

的功能,您可以在纯T-SQL写的唯一类型是标量和表值函数.

对于比较页面CREATE AGGREGATE,只列出了CLR样式选项,以CREATE FUNCTION,这表明T-SQL和CLR选项.

  • @Quandary只是一个建议:如果你告诉数据库管理员他需要在sql中启用clr并加载你的程序集当然他会说"哦,这是一个安全风险".但是,如果你有你的应用程序做所有工作,只是说"应用程序需要这些权利"(或更好,只是在安装程序中,所以只有安装程序需要这些权利),那么你更有可能获得批准.也许根本不是你的选择(我意识到这是一年前的问题)但我想我只是把那个想法扔出去了. (2认同)

Adr*_*der 13

看看像.这不是聚合函数.如果你想实现自己的聚合函数,它必须是CLR ...

DECLARE @Table TABLE(
        ID INT,
        Val VARCHAR(50)
)
INSERT INTO @Table (ID,Val) SELECT 1, 'A'
INSERT INTO @Table (ID,Val) SELECT 1, 'B'
INSERT INTO @Table (ID,Val) SELECT 1, 'C'
INSERT INTO @Table (ID,Val) SELECT 2, 'B'
INSERT INTO @Table (ID,Val) SELECT 2, 'C'

--Concat
SELECT  t.ID,
        SUM(t.ID),
        stuff(
                (
                    select  ',' + t1.Val
                    from    @Table t1
                    where   t1.ID = t.ID
                    order by t1.Val
                    for xml path('')
                ),1,1,'') Concats
FROM    @Table t
GROUP BY t.ID
Run Code Online (Sandbox Code Playgroud)