2

以下にリストされているデータを含む2つのテーブルを取得しました。

表1:学生

ここに画像の説明を入力してください

表2:件名

ここに画像の説明を入力してください

次のような出力が必要です。

ここに画像の説明を入力してください

XMLPATHに使用する以下のクエリでこれを達成しました

コード:

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パスを使用せずにこれを行うためのより良い方法はありますか?

4

1 に答える 1

2

これは非常に優れたアプローチであり、かなり受け入れられるようになりました。いくつかのアプローチがあり、このブログ投稿ではそれらの多くについて説明しています。

存在する興味深いアプローチの1つは、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 ;

これは明らかにかなり単純です。それが価値があるもののためにそれを取る:)

良い一日!

于 2012-08-22T02:36:55.617 に答える