【问题标题】:Comma Delimited Result set + SQL Query逗号分隔的结果集 + SQL 查询
【发布时间】:2012-08-22 02:26:51
【问题描述】:

我得到了两个数据表,如下所示:

表 1:学生

表 2:主题

我需要输出为:

我通过使用 XML PATH 的以下查询实现了这一目标

代码:

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 路径有更好的方法吗?

【问题讨论】:

    标签: sql-server-2008 tsql sql-server-2008-r2 for-xml-path


    【解决方案1】:

    这是一种非常好的方法,并且已被广泛接受。有几种方法,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 ;
    

    这显然要简单得多。物有所值:)

    美好的一天!

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 1970-01-01
      • 2014-04-22
      • 2021-11-17
      • 1970-01-01
      相关资源
      最近更新 更多