2012-08-22 207 views
2

我買了兩個數據表,列出如下:逗號分隔結果集+ SQL查詢

表1:學生

enter image description here

表2:主題

enter image description here

我需要輸出爲:

enter image description here

我這來達到的,使用了XML路徑下查詢

代碼:

WITH cte 
     AS (SELECT Stu.Student_Id , 
        Stu.Student_Name , 
        (SELECT Sub.[Subject] + ',' 
         FROM  [Subject] AS Sub 
         WHERE  Sub.Student_Id = Stu.Student_Id 
         ORDER BY Sub.[Subject] 
        FOR 
         XML PATH('') 
        ) AS [Subjects] 
      FROM  dbo.Student AS Stu 
     ) 
SELECT Student_id [Student Id] , 
     student_name [Student Name] , 
     SUBSTRING(Subjects, 1, (LEN(Subjects) - 1)) AS [Student Subjects] 
FROM cte 

我的問題是有沒有更好的方式來做到這一點,而不使用XML路徑?

回答

2

這是一個非常好的方法,並已被接受。有幾種方法,這blog post描述很多他們。

存在的一個有趣的方法是使用CLR爲您完成工作,這將顯着降低運行外部代碼的權衡的查詢的複雜性。下面是組件中類可能的樣例。

using System; 
using System.Collections.Generic; 
using System.Data.SqlTypes; 
using System.IO; 
using Microsoft.SqlServer.Server; 

[Serializable] 
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize=8000)] 
public struct strconcat : IBinarySerialize{ 

    private List values; 

    public void Init() { 
     this.values = new List(); 
    } 

    public void Accumulate(SqlString value) { 
     this.values.Add(value.Value); 
    } 

    public void Merge(strconcat value) { 
     this.values.AddRange(value.values.ToArray()); 
    } 

    public SqlString Terminate() { 
     return new SqlString(string.Join(", ", this.values.ToArray())); 
    } 

    public void Read(BinaryReader r) { 
     int itemCount = r.ReadInt32(); 
     this.values = new List(itemCount); 
     for (int i = 0; i <= itemCount - 1; i++) { 
      this.values.Add(r.ReadString()); 
     } 
    } 

    public void Write(BinaryWriter w) { 
     w.Write(this.values.Count); 
     foreach (string s in this.values)  { 
      w.Write(s); 
     } 
    } 
} 

而這將網絡查詢更像這樣。

SELECT CategoryId, 
      dbo.strconcat(ProductName) 
     FROM Products 
    GROUP BY CategoryId ; 

這顯然比較簡單一些。拿它來做它的價值:)

美好的一天!