SqlServer如何用Sql语句自定义聚合函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SqlServer如何用Sql语句自定义聚合函数相关的知识,希望对你有一定的参考价值。

我只要聚合函数,表值函数和标量函数就不要冒充了
我只要Sql语句创建聚合函数C#的 绕道
完美解答的 追加满分
如果回答完美 提高满 追加满

Sql Server自定义聚合函数详细步骤

开始->


输出->

首先用VS2008/VS2005建立一个SQL Server项目,右键解决方案添加新项

点击“确定”按钮后,SQL Server项目会要求连接一个数据库,我们可以选择一个数据库


然后在工程中加入一个聚合类(joinstr.cs),如图

joinstr.cs中的最终代码如下:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
                             
                             
[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined, //use custom serialization to serialize the intermediate result
    IsInvariantToNulls = true, //optimizer property
    IsInvariantToDuplicates = false, //optimizer property
    IsInvariantToOrder = false, //optimizer property    
    MaxByteSize = 8000), //maximum size in bytes of persisted value
]
                             
                             
public struct JoinStr:IBinarySerialize

    private StringBuilder sbIntermediate;
    public void Init()
    
       sbIntermediate = new StringBuilder();
    
                             
    public void Accumulate(SqlString Value)
    
                             
        if (Value == null || Value.ToString().ToLower().Equals("null"))
        
            return;
        
        else
        
            sbIntermediate.Append(Value);
        
    
                             
    public void Merge(JionStr Group)
    
        sbIntermediate.Append(Group.sbIntermediate);
    
                             
    public SqlString Terminate()
    
                                    
        return new SqlString(sbIntermediate.ToString());
    
                             
    // This is a place-holder member field
                             
                             
    #region IBinarySerialize Members
                             
    public void Read(System.IO.BinaryReader r)
    
        sbIntermediate = new StringBuilder(r.ReadString());
    
                             
    public void Write(System.IO.BinaryWriter w)
    
        w.Write(this.sbIntermediate.ToString());    
    
    #endregion

在编写完上述代码后,可以使用Visual Studio来部署(右向工程,在弹出菜单上选“部署”即可)。

在执行上面的SQL语句之前,需要将SQL Server2005的clr功能打开

现在可以使用joinstr来聚合字符串了。

select [t_code_role].[role_mc] as \'角色\',dbo.JoinStr([t_code_right].[right_mc]+\',\') as \'权限\' from [t_data_roleright],[t_code_right],[t_code_role] where [t_data_roleright].[role_bm]=[t_code_role].[role_bm] and [t_data_roleright].[right_bm]=[t_code_right].[right_bm] group by [t_code_role].[role_mc]

参考技术A

有两个写法:   

select * from tblDept
where id in(select DeptID from tblSalary group by DeptID having  
count(case when Salary>3000 then 1 else null end)*1.0/count(*)>0.5)

select * from tblDept
where id in(select DeptID from tblSalary group by DeptID having  
sum(case when Salary>3000 then 1 else 0 end)*1.0/count(*)>0.5)

参考技术B 我记得sql server 有function ,百度一下如何创建function。function与聚合函数是一回事。追问

那个创建的是标量行数

追答

function是自定义函数。

参考技术C 三楼回答的很好,标记一下,项目中要用到 参考技术D sql语句能实现吗?只知道sqlclr能实现追问

CLR? 确定新建出来的是 聚合函数?

追答

是啊。不知和你的想法一样吗?

1.clr中卡法,sql2008自带的vs功能
2.开发完成后,注册dll
3.再CREATE AGGREGATE 创建
4.就可以使用了

追问

我最后是在group by中使用,你测试过么?

追答

group by不能使用聚合函数或子查询,你就算写出聚合函数也不能用

追问

group by 前面只能使用聚合函数好不

sqlserver中怎么将一列数据拼接成一个字符串

1、自定义函数

2、使用connect by子语句的SQL,用sys_connect_by_path函数连接

3、自定义聚合函数

SQL SERVER日志清除的使用方法

1、设置数据库模式为简单模式:打开SQL企业管理器,在控制台根目录中依次点开Microsoft SQL Server-->SQL Server组-->双击打开你的服务器-->双击打开数据库目录-->选择你的数据库名称(如论坛数据库Forum)-->然后点击右键选择属性-->选择选项-->在故障还原的模式中选择“简单”,然后按确定保存。

2、在当前数据库上点右键,看所有任务中的收缩数据库,一般里面的默认设置不用调整,直接点确定。

3、收缩数据库完成后,建议将您的数据库属性重新设置为标准模式,操作方法同第一点,因为日志在一些异常情况下往往是恢复数据库的重要依据。

参考技术A 尚子素说的没错。
这种问题,我平常除了喜欢用动态sql写法,下来就是喜欢这个写法啦,
所以补充一下尚子素的说明:

首先,确定你要合并的列
SELECT user_name FROM dbo.users

其次,将其以xml格式输出
SELECT user_name FROM dbo.users FOR XML PATH

然后,去除包裹的节点名称
SELECT ',' +user_name FROM dbo.users FOR XML PATH('')
(这里,','+user_name以后变成了无列名状态,','可以填充具体的分隔符,PATH('')是自定义外层节点名称)

下来,去掉最终结果首位的分隔符,以空字符替代(PS:这样不用数长度)
SELECT STUFF((SELECT ','+user_name FROM dbo.users FOR XML PATH('')),1,1,'')
参考技术B 你的意思是单独一列数据,然后拼成一行数据,是这个意思吧。比如一列中有三行,分别是“天”“地”“人”。你现在想得到一行数据“天地人”,是这个意思吧。
那么方法就是for xml path,具体的写法要根据实际情况来写,这里只能说利用这个方法,到底怎么写就要根据你的字段具体写了。
要知道具体使用方法只要在baidu上搜索:sqlserver for xml path,就可以得到很多提示,比我写的好。
参考技术C

可以使用stuff函数结合xml path(),

比如:

SELECT STUFF( 
(SELECT ','+CONVERT(VARCHAR,sv.number) FROM MASTER.dbo.spt_values AS sv WHERE sv.[type]='p' AND sv.number <10 FOR XML PATH('')
),1,1,'')

结果为:0,1,2,3,4,5,6,7,8,9

参考技术D 列拼接,STUFF FOR XML PATH()方法,你可以查下的,这个讲的很多的,可以自定义中间的间隔符的,上面的那个例子就是其中之一

以上是关于SqlServer如何用Sql语句自定义聚合函数的主要内容,如果未能解决你的问题,请参考以下文章

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

sql server 2012 自定义聚合函数(MAX_O3_8HOUR_ND) 计算最大的臭氧8小时滑动平均值

sql server中啥是聚合函数

95-910-148-源码-FlinkSQL-Flink SQL自定义聚合函数

sqlserver 数据库 join 后面必须加 on吗?

sqlserver中怎么将一列数据拼接成一个字符串