
图1
其中要按着xh字段分组,并且将每一组name字段值连接起来。最终结果希望如图2所示

图2
xh value1 value2 value3 value4 .... .... value10
0001 123456 654321 456789
0002 12abcd 4d2r343 343dfd
0003 abcde3 132323
+ value10) as value from t_table让我们先看三条SQL语句:
select xh,value as th2 from t_table where th=2
select xh,value as th3 from t_table where th=3
这三条语句分别使用th字段按着所有th可能的值来查询t_table,这三条SQL语句所查询出来的记录如图3所示。

图 3
得到的结果如图4所示。

图4
(select xh from t_table group by xh) a
left join
(select xh,value as th1 from t_table where th=1) b on a.xh=b.xh
left join
(select xh,value as th2 from t_table where th=2) c on a.xh=c.xh
left join
(select xh,value as th3 from t_table where th=3) d on a.xh=d.xh
之所以使用left join,是因为按着th查询后,有的表的某些xh值可以没有,如图3中的第三个表,就没有0003。如果使用内连接,0003就无法在记录集中体现。这面的SQL的查询结果如图5所示。

图5
然后我们就可以使用如下的语句来连接th1、th2和th3了。
(
select a.xh, (case when b.th1 is null then '' else b.th1 end) as th1,
(case when c.th2 is null then '' else c.th2 end) as th2,
(case when d.th3 is null then '' else d.th3 end) as th3
from
(select xh from t_table group by xh) a
left join
(select xh,value as th1 from t_table where th=1) b on a.xh=b.xh
left join
(select xh,value as th2 from t_table where th=2) c on a.xh=c.xh
left join
(select xh,value as th3 from t_table where th=3) d on a.xh=d.xh
) x
三、使用C#实现SQL Server2005的扩展聚合函数(当然,也可以用VB.NET)
这一种方法笔者认为是最“酷”的方法。因为每一个人都只想写如下的SQL语句就可以达到目录。

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

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

图8
joinstr.cs中的最终代码如下:
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
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 System.Text.StringBuilder intermediateResult;
public void Init()
{
// 在此处放置代码
intermediateResult = new System.Text.StringBuilder();
}
public void Accumulate(SqlString Value)
{
intermediateResult.Append(Value.Value);
}
public void Merge(joinstr Group)
{
intermediateResult.Append(Group.intermediateResult);
}
public SqlString Terminate()
{
return new SqlString(intermediateResult.ToString());
}
public void Read(BinaryReader r)
{
intermediateResult = new StringBuilder(r.ReadString());
}
public void Write(BinaryWriter w)
{
w.Write(this.intermediateResult.ToString());
}
}
CREATE AGGREGATE joinstr (@input nvarchar(200)) RETURNS nvarchar(max)
EXTERNAL NAME MyAgg.joinstr
要注意的是,字符串类型需要用nvarchar,而不能用varchar。

图9
如果想删除上面建立的聚合函数,可以使用如下的SQL语句:
这种方法虽然显示很“酷”,但却要求开发人员熟悉扩展聚合函数的开发方法,如果开发人员使有的不是微软的开发工具,如使用Java,恐怕这种方法就只能是空谈了(除非开发小组内有人会用微软的开发工具)。
以上介绍的三种方法仅供参考,至于采用哪种方法,可根据实际需要和具体情况而定。如果哪位读者有更好的方法,请跟贴!
《银河系列原创教程》发布
















