【问题标题】:SQL Return subquery 'Total Records' to outer querySQL将子查询“总记录”返回到外部查询
【发布时间】:2016-04-24 03:41:38
【问题描述】:

这让我有点难过,我正试图从这个 SQL 查询中获取我的顶级(根)节点 XML 中的总数:

    SELECT COUNT(*) OVER() as '@totalCount', (
        SELECT COUNT(*) OVER() as totalCount, [Title], [Year], [Type], [Poster]
        FROM movies As result where CONTAINS(Title, @Title) Order by [Weight] DESC
        OFFSET ((@PageNumber - 1) * @RowspPage) ROWS
        FETCH NEXT @RowspPage ROWS ONLY
        FOR XML AUTO, type
    ) 
    FOR XML PATH('root')

显然COUNT(*)OVER() 只返回“1”,因为它是在顶层而不是在子查询中执行的。但我只想在根节点中显示一次,而不是每个结果都重复。

任何帮助将不胜感激。

【问题讨论】:

    标签: sql xml sql-server-2008 subquery


    【解决方案1】:

    编辑:这里是一个带有通用数据的工作示例:

    ;with myCTE as
    (
        select *
        from sys.objects
    )
    select (select count(*) from myCTE) as [@Counter]
        ,(
           SELECT myCTE.object_id AS id
                 ,mycte.name AS name 
           from myCTE
           for xml path('object'),TYPE
          )       
    for xml path('test')
    

    您可能会尝试将您的查询转换为 CTE 并将其放入如下内容:

    ;WITH MyQueryAsCTE AS
    (
        SELECT [Title], [Year], [Type], [Poster]
        FROM movies As result where CONTAINS(Title, @Title) Order by [Weight] DESC
        OFFSET ((@PageNumber - 1) * @RowspPage) ROWS
        FETCH NEXT @RowspPage ROWS ONLY
    )
    SELECT  (SELECT Count(*) FROM MyQueryAsCTE) as '@totalFound'
           ,[Title] AS [Movie/Title] 
           ,[Year] AS [Movie/Year]
           ,[Type] AS [Movie/Type]
           ,[Poster] AS [Movie/Poster]
    FROM MyQueryAsCTE
    FOR XML PATH('root')
    

    【讨论】:

    • 这几乎成功了!然而,它返回了“10”,这是我限制查询从 Offset/Fetch 返回的结果...
    • @bfritz 嗨,我用一个通用数据示例编辑了我的答案。这应该会引导你……
    • @bfritz,您将第二个选择包含在括号中并用FOR XML PATH ... , TYPE 调用它的想法显然是正确的......
    • 一旦我介绍了分页技术(偏移/获取),它只会返回我抑制查询的数量,而不是总数。
    • @bfritz 好吧,只需将“SELECT Count(*)...”更改为 (SELECT COUNT(*) FROM Movies) 这应该会得到完整的计数。
    【解决方案2】:

    字符串的乐趣...这完全是一个技巧,但它确实有效:

    DECLARE @totalCount AS INT
    DECLARE @result varchar(MAX)
    
    SELECT @totalCount = COUNT(*) OVER(), @result = COALESCE(@result + '', '') + '<result title="' + [Title] + '" year="' + [Year] + '" type="' + [Type] + '"/>'
    FROM Movies where CONTAINS(Title, '@Title') Order by [Weight] DESC
    OFFSET ((@PageNumber - 1) * @RowspPage) ROWS
    FETCH NEXT @RowspPage ROWS ONLY
    SELECT '<root totalCount="' + CAST(@totalCount AS VARCHAR) + '">' + @result + '</root>'
    

    输出:

    似乎有一个更快/更有效的执行计划,因为计算只进行一次,不需要对任何表进行额外查询。

    【讨论】:

    • 很高兴您找到了解决方案!但请注意,这种字符串连接方法SELECT @variable=@variable + ... 并不是绝对可靠的,而且 - 关于长字符串 - 正常执行时非常很差。我很确定,有一种方法可以获得COUNT(*) OVER() 的结果,并以与我的回答中指出的相同方式使用它。但没关系,快乐编码!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2011-07-18
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多