微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – SQL Server 2000:用于执行连接聚合子查询的想法

我有一个返回我想要的行的查询,例如
QuestionID  QuestionTitle  UpVotes  DownVotes  
==========  =============  =======  =========  
2142075     Win32: Cre...        0          0  
2232727     Win32: How...        2          0  
1870139     Wondows Ae...       12          0

现在我希望返回一个列,其中包含逗号分隔的“作者”列表(例如原始海报和编辑).例如.:

QuestionID  QuestionTitle  UpVotes  DownVotes  Authors
==========  =============  =======  =========  ==========
2142075     Win32: Cre...        0          0  Ian Boyd  
2232727     Win32: How...        2          0  Ian Boyd,roygbiv
1870139     Wondows Ae...       12          0  Ian Boyd,Aaron Klotz,Jason Diller,danbystrom

作假

sql Server 2000没有CONCAT(AuthorName,’,’)聚合操作,我一直伪造它 – 为TOP 1作者和作者计数执行简单的子选择.

QuestionID  QuestionTitle  UpVotes  DownVotes  FirstAuthor  AuthorCount  
==========  =============  =======  =========  ===========  =========== 
2142075     Win32: Cre...        0          0  Ian Boyd               1 
2232727     Win32: How...        2          0  Ian Boyd               2
1870139     Wondows Ae...       12          0  Ian Boyd               3

如果有多个作者,那么我向用户显示一个省略号(“…”),表示有多个.例如用户会看到:

QuestionID  QuestionTitle  UpVotes  DownVotes  Authors
==========  =============  =======  =========  ==========
2142075     Win32: Cre...        0          0  Ian Boyd
2232727     Win32: How...        2          0  Ian Boyd,…
1870139     Wondows Ae...       12          0  Ian Boyd,…

这很有效,因为通常一个问题不会被编辑 – 这意味着我完全支持99%的情况,1%的情况也只有一半.

线程重新查询

作为一个更复杂,容易出错的解决方案,我正在考虑迭代显示的列表,并为列表中的每个“问题”启动线程池工作线程,对数据库执行查询获取作者列表,然后在内存中聚合列表.这意味着列表首先填充(本机)应用程序.然后我发出几千个单独的查询.

但那将是可怕的,可怕的,非常的,缓慢的.更不用说bug-riddled,因为它将是线程工作.

耶耶耶

Adam Mechanic says quite plainly

Don’t concatenate rows into delimited
strings in sql Server. Do it client
side.

告诉我怎么做,我会做的.

/哭

任何人都可以想到一个更好的解决方案,就像我原来的“TOP 1 plus ellipses”解决方案一样快(比如说…在一个数量级内)?

例如,有没有办法返回结果集,其中到达行有关联的结果集?因此,对于每个“主”行,我可以获得包含列表的“详细信息”结果集.

代码为最佳答案

Cade’s链接Adam Machanic’s solution我最喜欢.用户定义的函数,似乎通过魔术操作:

CREATE FUNCTION dbo.ConcatAuthors(@QuestionID int)
RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE @Output VARCHAR(8000)
    SET @Output = ''

    SELECT @Output =    CASE @Output 
                WHEN '' THEN AuthorName 
                ELSE @Output + ',' + AuthorName 
                END
    FROM  (
        SELECT QuestionID,AuthorName,QuestionDate AS AuthorDate FROM Questions
        UNION
        SELECT QuestionID,EditorName,EditDate FROM QuestionEdits
    ) dt
    WHERE dt.QuestionID = @QuestionID
    ORDER BY AuthorDate

    RETURN @Output
END

使用T-sql

SELECT QuestionID,QuestionTitle,UpVotes,DownVotes,dbo.ConcatAuthors(AuthorID)
FROM Questions

解决方法

看看这些文章

http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/rowset-string-concatenation-which-method-is-best.aspx

http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/(请参阅响应中的Phil Factor的交叉连接解决方​​案 – 这将在sql Server 2000中有效)

显然在sql Server 2005中,FOR XML技巧最简单,最灵活,通常效率最高.

至于为每一行返回行集,如果由于某种原因仍然想要这样做,可以在存储过程中执行此操作,但客户端需要使用第一行集中的所有行,然后转到下一行rowset并将其与第一个行集中的第一行相关联等.您的SP需要在它作为第一个行集返回的同一个集合上打开一个游标,并按顺序运行多个选择以生成所有子行集.这是我已经完成的一项技术,但仅限于实际需要所有数据的地方(例如,在完全填充的树视图中).

无论人们怎么说,做客户端通常都是浪费带宽,因为返回所有行并在客户端进行循环和中断意味着在开始时传输了大量相同的列.每行只是为了获得行尾的更改列.

无论您在何处进行,都应根据您的使用案例做出明智的决定.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐